Skip to content

Commit

Permalink
Merge pull request #3 from permafrost-dev/add-result-nodes
Browse files Browse the repository at this point in the history
Add Result Nodes
  • Loading branch information
patinthehat authored Jul 6, 2021
2 parents 74ae2ff + 5c3e0e9 commit 4e64e6e
Show file tree
Hide file tree
Showing 19 changed files with 162 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ All notable changes to `php-code-search` will be documented in this file.
## 1.4.0 - 2021-07-05

- allow searching for static method calls like `MyClass` or `MyClass::someMethod`
- add `ResultNode` class
- add `node` property to `SearchResult` class

## 1.3.2 - 2021-07-05

Expand Down
27 changes: 20 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ To search a file, use the `search` method. Its only parameter may be either a s

To search a string instead, use the `searchCode` method.

The search methods return an instance of `Permafrost\PhpCodeSearch\Results\FileSearchResults`, which has a `results` property.

Each `result` is an instance of `Permafrost\PhpCodeSearch\Results\SearchResult` with the following properties:

- `node` - the specific item that was found
- `node->name(): string`
- `location` - the location in the file that the item was found
- `location->startLine(): int`
- `location->endLine(): int`
- `snippet` - a snippet of code lines from the file with the result line in the middle
- `snippet->getCode(): string`
- `file()` _(method)_ - provides access to the file that was searched

### Variable names

To search for variables by name, use the `variables` method before calling `search`. To use regular expressions, surround the values with `/`.
Expand All @@ -41,7 +54,7 @@ $results = $searcher
->searchCode('<?php $oneA = "1a"; $oneB = "1b"; $oneC = "1c"; $twoA = "2a"; $twoB = "2b";');

foreach($results as $result) {
echo "Found '{$result->location->name}' on line {$result->location->startLine}" . PHP_EOL;
echo "Found '{$result->node->name()}' on line {$result->location->startLine}" . PHP_EOL;
}
```

Expand All @@ -59,7 +72,7 @@ $results = $searcher
->search('./file1.php');

foreach($results as $result) {
echo "Found '{$result->location->name}' on line {$result->location->startLine}" . PHP_EOL;
echo "Found '{$result->node->name()}' on line {$result->location->startLine}" . PHP_EOL;
}
```

Expand All @@ -80,7 +93,7 @@ $results = $searcher
'');

foreach($results as $result) {
echo "Found '{$result->location->name}' on line {$result->location->startLine}" . PHP_EOL;
echo "Found '{$result->node->name()}' on line {$result->location->startLine}" . PHP_EOL;
}
```

Expand All @@ -100,7 +113,7 @@ $results = $searcher
->search('./app/Http/Controllers/MyController.php');

foreach($results as $result) {
echo "Found '{$result->location->name}' on line {$result->location->startLine}" . PHP_EOL;
echo "Found '{$result->node->name()}' on line {$result->location->startLine}" . PHP_EOL;
}
```

Expand All @@ -118,7 +131,7 @@ $results = $searcher
->search('./app/Http/Controllers/MyController.php');

foreach($results as $result) {
echo "Found '{$result->location->name}' on line {$result->location->startLine}" . PHP_EOL;
echo "Found '{$result->node->name()}' on line {$result->location->startLine}" . PHP_EOL;
}
```

Expand All @@ -136,7 +149,7 @@ $results = $searcher
->search('./app/Http/Controllers/MyController.php');

foreach($results as $result) {
echo "Found '{$result->location->name}' on line {$result->location->startLine}" . PHP_EOL;
echo "Found '{$result->node->name()}' on line {$result->location->startLine}" . PHP_EOL;
}
```

Expand All @@ -154,7 +167,7 @@ $results = $searcher
->searchCode('<?php $str = strtolower("TEST");');

foreach($results as $result) {
echo "Found '{$result->location->name}' on line {$result->location->startLine}" . PHP_EOL;
echo "Found '{$result->node->name()}' on line {$result->location->startLine}" . PHP_EOL;
}
```

Expand Down
5 changes: 3 additions & 2 deletions src/Results/FileSearchResults.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Permafrost\PhpCodeSearch\Code\CodeLocation;
use Permafrost\PhpCodeSearch\Code\CodeSnippet;
use Permafrost\PhpCodeSearch\Results\Nodes\ResultNode;
use Permafrost\PhpCodeSearch\Support\File;

class FileSearchResults
Expand All @@ -26,11 +27,11 @@ public function __construct(File $file, bool $withSnippets = true)
$this->withSnippets = $withSnippets;
}

public function addLocation(CodeLocation $location): self
public function add(ResultNode $resultNode, CodeLocation $location): self
{
$snippet = $this->makeSnippet($location->startLine());

$this->results[] = new SearchResult($location, $snippet, $this->file);
$this->results[] = new SearchResult($resultNode, $location, $snippet, $this->file);

return $this;
}
Expand Down
24 changes: 24 additions & 0 deletions src/Results/Nodes/FunctionCallNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

class FunctionCallNode implements ResultNode
{
/** @var string */
public $name;

public function __construct(string $name)
{
$this->name = $name;
}

public static function create(string $name): self
{
return new static(...func_get_args());
}

public function name(): string
{
return $this->name;
}
}
8 changes: 8 additions & 0 deletions src/Results/Nodes/ResultNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

interface ResultNode
{
public function name(): string;
}
32 changes: 32 additions & 0 deletions src/Results/Nodes/StaticMethodCallNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

class StaticMethodCallNode implements ResultNode
{
/** @var string */
public $className;

/** @var string */
public $methodName;

/** @var string */
public $name;

public function __construct(string $className, string $methodName)
{
$this->className = $className;
$this->methodName = $methodName;
$this->name = $this->name();
}

public static function create(string $className, string $methodName): self
{
return new static(...func_get_args());
}

public function name(): string
{
return "{$this->className}::{$this->methodName}";
}
}
24 changes: 24 additions & 0 deletions src/Results/Nodes/VariableNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Permafrost\PhpCodeSearch\Results\Nodes;

class VariableNode implements ResultNode
{
/** @var string */
public $name;

public function __construct(string $name)
{
$this->name = $name;
}

public static function create(string $name): self
{
return new static(...func_get_args());
}

public function name(): string
{
return $this->name;
}
}
11 changes: 10 additions & 1 deletion src/Results/SearchResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,35 @@
use Permafrost\PhpCodeSearch\Code\CodeSnippet;
use Permafrost\PhpCodeSearch\Code\FunctionCallLocation;
use Permafrost\PhpCodeSearch\Code\StaticMethodCallLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\FunctionCallNode;
use Permafrost\PhpCodeSearch\Results\Nodes\ResultNode;
use Permafrost\PhpCodeSearch\Results\Nodes\StaticMethodCallNode;
use Permafrost\PhpCodeSearch\Results\Nodes\VariableNode;
use Permafrost\PhpCodeSearch\Support\File;

class SearchResult
{
/** @var CodeLocation|FunctionCallLocation|StaticMethodCallLocation */
public $location;

/** @var ResultNode|FunctionCallNode|StaticMethodCallNode|VariableNode */
public $node;

/** @var CodeSnippet|null */
public $snippet;

/** @var File */
protected $file;

/**
* @param ResultNode $node
* @param CodeLocation $location
* @param CodeSnippet|null $snippet
* @param File|string $file
*/
public function __construct(CodeLocation $location, ?CodeSnippet $snippet, $file)
public function __construct(ResultNode $node, CodeLocation $location, ?CodeSnippet $snippet, $file)
{
$this->node = $node;
$this->location = $location;
$this->snippet = $snippet;
$this->file = is_string($file) ? new File($file) : $file;
Expand Down
26 changes: 20 additions & 6 deletions src/Visitors/FunctionCallVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use Permafrost\PhpCodeSearch\Code\FunctionCallLocation;
use Permafrost\PhpCodeSearch\Code\StaticMethodCallLocation;
use Permafrost\PhpCodeSearch\Results\FileSearchResults;
use Permafrost\PhpCodeSearch\Results\Nodes\FunctionCallNode;
use Permafrost\PhpCodeSearch\Results\Nodes\StaticMethodCallNode;
use Permafrost\PhpCodeSearch\Results\Nodes\VariableNode;
use Permafrost\PhpCodeSearch\Support\Arr;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
Expand All @@ -30,71 +33,82 @@ public function enterNode(Node $node)
{
if ($node instanceof FuncCall) {
if (Arr::matches($node->name, $this->functionNames, true)) {
$resultNode = FunctionCallNode::create($node->name->toString());

$location = FunctionCallLocation::create(
$node->name->parts[0],
$node->getStartLine(),
$node->getEndLine()
);

$this->results->addLocation($location);
$this->results->add($resultNode, $location);
}
}

if ($node instanceof Node\Expr\StaticCall) {
$resultNode = StaticMethodCallNode::create($node->class->toString(), $node->name->toString());

$location = StaticMethodCallLocation::create(
$node->class->parts[0],
$node->name->toString(),
$node->getStartLine(),
$node->getEndLine()
);

$this->results->addLocation($location);
$this->results->add($resultNode, $location);
}

if ($node instanceof Node\Expr\MethodCall) {
$resultNode = FunctionCallNode::create($node->name->toString());

$location = FunctionCallLocation::create(
$node->name->toString(),
$node->getStartLine(),
$node->getEndLine()
);

$this->results->addLocation($location);
$this->results->add($resultNode, $location);
}

if ($node instanceof Node\Expr\Variable) {
if (Arr::matches($node->name, $this->variableNames, true)) {
$resultNode = VariableNode::create($node->name);

$location = FunctionCallLocation::create(
$node->name,
$node->getStartLine(),
$node->getEndLine()
);

$this->results->addLocation($location);
$this->results->add($resultNode, $location);
}
}

if ($node instanceof Node\Expr\New_) {
$resultNode = VariableNode::create($node->class->toString());

$location = FunctionCallLocation::create(
$node->class->parts[0],
$node->getStartLine(),
$node->getEndLine()
);

$this->results->addLocation($location);
$this->results->add($resultNode, $location);
}

if ($node instanceof Node\Expr\Assign) {
// print_r($node->expr->getSubNodeNames());
// print_r($node->var->getSubNodeNames());
// print_r([$node->var->name]);
$resultNode = FunctionCallNode::create($node->var->name);

$location = FunctionCallLocation::create(
$node->var->name,
$node->getStartLine(),
$node->getEndLine()
);

$this->results->addLocation($location);
$this->results->add($resultNode, $location);
}
}
}
4 changes: 3 additions & 1 deletion tests/Results/SearchResultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Permafrost\PhpCodeSearch\Code\CodeSnippet;
use Permafrost\PhpCodeSearch\Code\FunctionCallLocation;
use Permafrost\PhpCodeSearch\Results\Nodes\VariableNode;
use Permafrost\PhpCodeSearch\Results\SearchResult;
use Permafrost\PhpCodeSearch\Support\File;
use PHPUnit\Framework\TestCase;
Expand All @@ -19,7 +20,8 @@ public function it_creates_the_object_with_correct_properties()
$file = new File(tests_path('data/file2.txt'));
$location = new FunctionCallLocation('my_func', 1, 1);
$snippet = (new CodeSnippet())->fromFile($file);
$result = new SearchResult($location, $snippet, $file);
$resultNode = new VariableNode('myVar');
$result = new SearchResult($resultNode, $location, $snippet, $file);

$this->assertMatchesObjectSnapshot($result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ location:
column: 0
endLine: 1
startLine: 1
node:
name: myVar
snippet:
code: { 1: '1', 2: '2', 3: '3', 4: '4', 5: '5' }
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-
location: { name: strtolower, column: 0, endLine: 2, startLine: 2 }
node: { name: strtolower }
snippet: { code: { 1: '<?php', 2: '$myVar = strtolower(''test'');' } }
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-
location: { name: MyClass, column: 0, endLine: 13, startLine: 13 }
node: { name: MyClass }
snippet: { code: { 9: ' {', 10: ' Ray::rateLimiter()->count(5);', 11: ' }', 12: '', 13: ' $obj = new MyClass();', 14: '', 15: ' $obj->withData([123])->send();', 16: '' } }
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
-
location: { name: strtolower, column: 0, endLine: 4, startLine: 4 }
node: { name: strtolower }
snippet: { code: { 1: '<?php', 2: ' ray(''12345'');', 3: '', 4: ' printf("%s\n", strtolower(''TEST''));', 5: '', 6: ' echo strtoupper(''test'') . PHP_EOL;', 7: '', 8: ' function test1()' } }
-
location: { name: strtoupper, column: 0, endLine: 6, startLine: 6 }
node: { name: strtoupper }
snippet: { code: { 2: ' ray(''12345'');', 3: '', 4: ' printf("%s\n", strtolower(''TEST''));', 5: '', 6: ' echo strtoupper(''test'') . PHP_EOL;', 7: '', 8: ' function test1()', 9: ' {' } }
Loading

0 comments on commit 4e64e6e

Please sign in to comment.