Skip to content

Commit 7e3a19b

Browse files
committed
only forward paths
1 parent e532fc2 commit 7e3a19b

File tree

14 files changed

+54
-20
lines changed

14 files changed

+54
-20
lines changed

.devcontainer/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ RUN apt-get install -y git curl vim bash sudo tmux man ack zip unzip
66

77
# nikic/php-ast
88
RUN cd /tmp; git clone https://github.com/nikic/php-ast.git && cd php-ast && phpize && ./configure && make && make install
9-
RUN echo "extension=ast" > /usr/local/etc/php/conf.d/docker-php-ast.ini
9+
RUN echo "extension=ast" > /usr/local/etc/php/conf.d/php-ast.ini
1010

1111
# xdebug
1212
RUN cd /tmp; curl -O https://xdebug.org/files/xdebug-3.2.1.tgz && tar -xvzf xdebug-3.2.1.tgz && cd xdebug-3.2.1 && phpize && ./configure && make && make install
13+
RUN echo "zend_extension=xdebug" > /usr/local/etc/php/conf.d/xdebug.ini
1314

1415
# Composer
1516
RUN cd /tmp; curl -O https://getcomposer.org/installer && php ./installer --install-dir=/usr/local/bin --filename=composer

src/Paths/FunctionPaths.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ public function isEmpty(): bool
5454
public function toString(?int $max_length = null): string
5555
{
5656
if ($this->isEmpty()) {
57-
return $this->function_name;
57+
return '';
5858
}
5959

6060
$paths = $this->paths;
61-
if ($max_length !== null) {
61+
if ($max_length !== null && count($paths) > $max_length) {
6262
shuffle($paths);
6363
$paths = array_slice($paths, 0, $max_length);
6464
}

src/Paths/GraphNode/NonTerminal.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,32 @@ public function allPathsToTerminals(PartialPath $prefix): \Generator
4242
$previous_node = $prefix->lastNode();
4343
$prefix = $prefix->withNonTerminal($this);
4444

45-
// TODO: Only allow forward paths?
45+
// Only follow "forward" paths by only going to children with
46+
// greater indices than the previous node on the path.
47+
//
48+
// n.b.: This assumes that the indices of `$children` are
49+
// monotonically incrementing by 1. If this ever isn't the case
50+
// we'll need to call `array_values` on it.
51+
$starting_index = array_search($previous_node, $this->children, $strict = true);
52+
if ($starting_index === false) {
53+
$starting_index = -1;
54+
}
55+
56+
if ($starting_index + 1 <= count($this->children) - 1) {
57+
foreach (range($starting_index + 1, count($this->children) - 1) as $i) {
58+
yield from $this->children[$i]->allPathsToTerminals($prefix);
59+
}
60+
}
61+
62+
/*
4663
foreach ($this->children as $child) {
4764
// Skip the node we just popped out of
4865
if ($child === $previous_node) {
4966
continue;
5067
}
5168
yield from $child->allPathsToTerminals($prefix);
5269
}
70+
*/
5371
}
5472

5573
/**

src/Paths/GraphNodeVisitor.php

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@ public function __construct(GraphNode $parent = null, bool $use_node_ids = false
2121
$this->use_node_ids = $use_node_ids;
2222
}
2323

24+
public function newGraphNodeVisitorWithParent(GraphNode $parent = null)
25+
{
26+
return new GraphNodeVisitor($parent, $this->use_node_ids);
27+
}
28+
2429
/**
2530
* @param $node Node|null|string|int
2631
*/
2732
public function graphNodeFromNodeOrValue($node, GraphNode $parent): GraphNode
2833
{
2934
if ($node instanceof Node) {
30-
return (new GraphNodeVisitor($parent, $this->use_node_ids))($node);
35+
return $this->newGraphNodeVisitorWithParent($parent)($node);
3136
}
3237
return self::terminalFromNodeOrValue($node, $parent);
3338
}
@@ -109,7 +114,7 @@ public function visitParamList(Node $node): GraphNode
109114

110115
$gn = new NonTerminal($this->nodeName($node), $this->parent);
111116
foreach ($node->children ?? [] as $param) {
112-
$gn->appendChild((new GraphNodeVisitor($gn))($param));
117+
$gn->appendChild($this->newGraphNodeVisitorWithParent($gn)($param));
113118
}
114119
return $gn;
115120
}
@@ -147,22 +152,22 @@ public function visitForeach(Node $node): GraphNode
147152

148153
$expr = $node->children['expr'] ?? null;
149154
if ($expr instanceof Node) {
150-
$gn->appendChild((new GraphNodeVisitor($gn))($expr));
155+
$gn->appendChild($this->newGraphNodeVisitorWithParent($gn)($expr));
151156
}
152157

153158
$value = $node->children['value'] ?? null;
154159
if ($value instanceof Node) {
155-
$gn->appendChild((new GraphNodeVisitor($gn))($value));
160+
$gn->appendChild($this->newGraphNodeVisitorWithParent($gn)($value));
156161
}
157162

158163
$key = $node->children['key'] ?? null;
159164
if ($key instanceof Node) {
160-
$gn->appendChild((new GraphNodeVisitor($gn))($key));
165+
$gn->appendChild($this->newGraphNodeVisitorWithParent($gn)($key));
161166
}
162167

163168
$stmts = $node->children['stmts'] ?? null;
164169
if ($stmts instanceof Node) {
165-
$gn->appendChild((new GraphNodeVisitor($gn))($stmts));
170+
$gn->appendChild($this->newGraphNodeVisitorWithParent($gn)($stmts));
166171
}
167172

168173
return $gn;
@@ -173,7 +178,7 @@ public function visitIf(Node $node): GraphNode
173178
$gn = new NonTerminal($this->nodeName($node), $this->parent);
174179

175180
foreach ($node->children as $child) {
176-
$gn->appendChild((new GraphNodeVisitor($gn))($child));
181+
$gn->appendChild($this->newGraphNodeVisitorWithParent($gn)($child));
177182
}
178183

179184
return $gn;

src/Paths/Subtokens.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ final class Subtokens
1212
*/
1313
public static function fromString(string $string): array
1414
{
15+
16+
// Replace special characters
1517
$string = str_replace([',', '|', '\\', '"', "'"], ['comma', 'pipe', 'slash', 'quote', "quote"], $string);
1618

1719
// Collapse whitespace
1820
$string = trim(preg_replace('/\s+/', ' ', $string));
1921

22+
// Remove non-ascii
23+
$string = preg_replace('/[[:^print:]]/', '', $string);
24+
2025
// Replace all-caps `FOO` with `Foo`.
2126
$string = preg_replace_callback('/([A-Z])([A-Z]+)/', function ($matches) {
2227
return $matches[1] . strtolower($matches[2]);

src/paths.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
if ($function_paths->isEmpty()) {
6565
continue;
6666
}
67+
// print(memory_get_usage()/1024/1024 . " " . memory_get_peak_usage()/1024/1024 . "\n");
6768
print $function_paths->toString($max_length) . "\n";
6869
}
6970
});

tests/FunctionPathsTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ public static function caseProvider(): array
2424
#[DataProvider('caseProvider')]
2525
public function testCases($actual_file, $expected_file): void
2626
{
27-
$actual_paths = implode("\n", array_map(function (FunctionPaths $path): string {
27+
$actual_paths = implode("\n", array_filter(array_map(function (FunctionPaths $path): string {
2828
return $path->toString();
29-
}, iterator_to_array(FunctionPaths::fromFileName($actual_file))));
29+
}, iterator_to_array(FunctionPaths::fromFileName($actual_file)))));
3030
$expected_paths = trim(file_get_contents($expected_file));
3131

3232
$this->assertEquals($actual_paths, $expected_paths);

tests/SubtokensTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public function testKebabCase(): void
3737
{
3838
$this->assertEquals(
3939
Subtokens::fromString('foo-bar'),
40-
['foo', 'bar']
40+
['foo', 'bar'],
41+
'this'
4142
);
4243
}
4344

@@ -112,5 +113,10 @@ public function testSpecialCharacters(): void {
112113
Subtokens::fromString(", | \\ \" '"),
113114
['comma', 'pipe', 'slash', 'quote', 'quote']
114115
);
116+
117+
$this->assertEquals(
118+
Subtokens::fromString('aAÂ'),
119+
['a', 'a']
120+
);
115121
}
116122
}

tests/cases/0003_function.c2s

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
f

tests/cases/0004_function.c2s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
f long,parameter,x long,parameter|function|return|variable,x x,parameter,long x,parameter|function|return|variable,x x,variable|return|function|parameter,long x,variable|return|function|parameter,x
1+
f long,parameter,x long,parameter|function|return|variable,x x,parameter|function|return|variable,x

0 commit comments

Comments
 (0)