diff --git a/src/NodeVisitors/NodeAtPositionFinder.php b/src/NodeVisitors/NodeAtPositionFinder.php index 35de06f..8f38eec 100644 --- a/src/NodeVisitors/NodeAtPositionFinder.php +++ b/src/NodeVisitors/NodeAtPositionFinder.php @@ -4,7 +4,7 @@ declare(strict_types = 1); namespace LanguageServer\NodeVisitors; use PhpParser\{NodeVisitorAbstract, Node}; -use LanguageServer\Protocol\Position; +use LanguageServer\Protocol\{Position, Range}; /** * Finds the Node at a specified position @@ -34,13 +34,11 @@ class NodeAtPositionFinder extends NodeVisitorAbstract public function leaveNode(Node $node) { - if ( - !isset($this->node) - && $node->getAttribute('startLine') <= $this->position->line + 1 - && $node->getAttribute('endLine') >= $this->position->line + 1 - && $node->getAttribute('startColumn') <= $this->position->character + 1 - && $node->getAttribute('endColumn') >= $this->position->character + 1 - ) { + $range = new Range( + new Position($node->getAttribute('startLine') - 1, $node->getAttribute('startColumn') - 1), + new Position($node->getAttribute('endLine') - 1, $node->getAttribute('endColumn') - 1) + ); + if (!isset($this->node) && $range->includes($this->position)) { $this->node = $node; } } diff --git a/src/Protocol/Position.php b/src/Protocol/Position.php index 7831268..01cff0b 100644 --- a/src/Protocol/Position.php +++ b/src/Protocol/Position.php @@ -26,4 +26,27 @@ class Position $this->line = $line; $this->character = $character; } + + /** + * Compares this position to another position + * Returns + * - 0 if the positions match + * - a negative number if $this is before $position + * - a positive number otherwise + * + * @param Position $position + * @return int + */ + public function compare(Position $position): int + { + if ($this->line === $position->line && $this->character === $position->character) { + return 0; + } + + if ($this->line !== $position->line) { + return $this->line - $position->line; + } + + return $this->character - $position->character; + } } diff --git a/src/Protocol/Range.php b/src/Protocol/Range.php index c4a59ff..56dba0c 100644 --- a/src/Protocol/Range.php +++ b/src/Protocol/Range.php @@ -26,4 +26,15 @@ class Range $this->start = $start; $this->end = $end; } + + /** + * Checks if a position is within the range + * + * @param Position $position + * @return bool + */ + public function includes(Position $position): bool + { + return $this->start->compare($position) <= 0 && $this->end->compare($position) >= 0; + } }