From f785f67ca89a1a10258268f7e85440a0235f4d39 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sat, 15 Mar 2025 08:49:58 +0000 Subject: [PATCH 1/8] Add VariableParser and VariableContext Fixes N1ebieski/vs-code-php-parser-cli#5 --- app/Contexts/Variable.php | 22 +++++++++++++++++ app/Parsers/VariableParser.php | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 app/Contexts/Variable.php create mode 100644 app/Parsers/VariableParser.php diff --git a/app/Contexts/Variable.php b/app/Contexts/Variable.php new file mode 100644 index 0000000..4b691fc --- /dev/null +++ b/app/Contexts/Variable.php @@ -0,0 +1,22 @@ + $this->name, + ]; + } +} diff --git a/app/Parsers/VariableParser.php b/app/Parsers/VariableParser.php new file mode 100644 index 0000000..e0fd7bc --- /dev/null +++ b/app/Parsers/VariableParser.php @@ -0,0 +1,43 @@ +context->name = $node->getName(); + + if (Settings::$capturePosition) { + $range = PositionUtilities::getRangeFromPosition( + $node->getStartPosition(), + mb_strlen($node->getText()), + $node->getRoot()->getFullText(), + ); + + if (Settings::$calculatePosition !== null) { + $range = Settings::adjustPosition($range); + } + + $this->context->setPosition($range); + } + + return $this->context; + } + + public function initNewContext(): ?AbstractContext + { + return new VariableContext; + } +} From f8016ad5c32a990df7fd544e3f5d207da1d01d50 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sun, 30 Mar 2025 09:45:32 +0000 Subject: [PATCH 2/8] Support for VariableParser for autocomplete Fixes N1ebieski/vs-code-php-parser-cli#8 --- app/Contexts/AbstractContext.php | 14 ++++++++++---- app/Contexts/MethodCall.php | 2 ++ app/Contexts/ObjectValue.php | 2 ++ app/Contexts/Variable.php | 2 ++ app/Parser/Walker.php | 14 +++++++++++++- app/Parsers/VariableParser.php | 13 +++++++++++++ 6 files changed, 42 insertions(+), 5 deletions(-) diff --git a/app/Contexts/AbstractContext.php b/app/Contexts/AbstractContext.php index b241b77..cc12a15 100644 --- a/app/Contexts/AbstractContext.php +++ b/app/Contexts/AbstractContext.php @@ -9,6 +9,12 @@ abstract class AbstractContext { public array $children = []; + /** + * Whether this context can be found as last result + * in findAutocompleting method + */ + public bool $findable = false; + public bool $autocompleting = false; protected array $freshObject; @@ -48,20 +54,20 @@ public function flip() public function findAutocompleting(?AbstractContext $context = null) { $context = $context ?? $this; - $result = $this->seachForAutocompleting($context, true); + $result = $this->searchForAutocompleting($context, true); $lastResult = null; while ($result !== null) { $lastResult = $result; - $result = $this->seachForAutocompleting($result); + $result = $this->searchForAutocompleting($result); } return $lastResult; } - protected function seachForAutocompleting(AbstractContext $context, $checkCurrent = false) + protected function searchForAutocompleting(AbstractContext $context, $checkCurrent = false) { - if ($checkCurrent && $context->autocompleting && ($context instanceof MethodCall || $context instanceof ObjectValue)) { + if ($checkCurrent && $context->autocompleting && $context->findable) { return $context; } diff --git a/app/Contexts/MethodCall.php b/app/Contexts/MethodCall.php index 4e82220..6a81662 100644 --- a/app/Contexts/MethodCall.php +++ b/app/Contexts/MethodCall.php @@ -4,6 +4,8 @@ class MethodCall extends AbstractContext { + public bool $findable = true; + public ?string $methodName = null; public ?string $className = null; diff --git a/app/Contexts/ObjectValue.php b/app/Contexts/ObjectValue.php index 6d3ea44..71a5ca4 100644 --- a/app/Contexts/ObjectValue.php +++ b/app/Contexts/ObjectValue.php @@ -4,6 +4,8 @@ class ObjectValue extends AbstractContext { + public bool $findable = true; + public ?string $className = null; public Arguments $arguments; diff --git a/app/Contexts/Variable.php b/app/Contexts/Variable.php index 4b691fc..fd38be2 100644 --- a/app/Contexts/Variable.php +++ b/app/Contexts/Variable.php @@ -4,6 +4,8 @@ class Variable extends AbstractContext { + public bool $findable = true; + public ?string $name = null; protected bool $hasChildren = false; diff --git a/app/Parser/Walker.php b/app/Parser/Walker.php index d2c2f5f..b92f5e1 100644 --- a/app/Parser/Walker.php +++ b/app/Parser/Walker.php @@ -49,9 +49,21 @@ protected function documentSkipsClosingQuote() return false; } + protected function documentSkipsObjectOperator(): bool + { + if (count($this->sourceFile->statementList) === 1 && $this->sourceFile->statementList[0] instanceof InlineHtml) { + $lastChars = substr($this->sourceFile->getFullText(), -2); + $closesWithObjectOperator = $lastChars === '->'; + + return $closesWithObjectOperator; + } + + return false; + } + public function walk() { - if (!$this->documentSkipsClosingQuote()) { + if (!$this->documentSkipsClosingQuote() && !$this->documentSkipsObjectOperator()) { return new Base; } diff --git a/app/Parsers/VariableParser.php b/app/Parsers/VariableParser.php index e0fd7bc..ed9004e 100644 --- a/app/Parsers/VariableParser.php +++ b/app/Parsers/VariableParser.php @@ -15,8 +15,21 @@ class VariableParser extends AbstractParser */ protected AbstractContext $context; + /** + * Check if the variable has a object operator and + * is a last element in the string + */ + private function isAutocompleting(Variable $node): bool + { + return preg_match('/\$' . $node->getName() . '->;$/s', $node->getFileContents()); + } + public function parse(Variable $node) { + if ($this->isAutocompleting($node)) { + $this->context->autocompleting = true; + } + $this->context->name = $node->getName(); if (Settings::$capturePosition) { From 4f8548acaddace1425a47d7911c7cfc506bbc77f Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sun, 30 Mar 2025 10:14:19 +0000 Subject: [PATCH 3/8] Support for VariableParser for autocomplete Fixes N1ebieski/vs-code-php-parser-cli#8 --- app/Parsers/MemberAccessExpressionParser.php | 15 +++++++++++++++ app/Parsers/VariableParser.php | 10 ++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/Parsers/MemberAccessExpressionParser.php b/app/Parsers/MemberAccessExpressionParser.php index e087dc4..11af318 100644 --- a/app/Parsers/MemberAccessExpressionParser.php +++ b/app/Parsers/MemberAccessExpressionParser.php @@ -17,8 +17,23 @@ class MemberAccessExpressionParser extends AbstractParser */ protected AbstractContext $context; + /** + * Check if the node has a object operator and + * is a last element in the string + */ + private function hasObjectOperator(MemberAccessExpression $node): bool + { + $name = $node->memberName->getFullText($node->getRoot()->getFullText()); + + return preg_match('/->' . $name . '->;$/s', $node->getFileContents()); + } + public function parse(MemberAccessExpression $node) { + if ($this->hasObjectOperator($node)) { + $this->context->autocompleting = true; + } + $this->context->methodName = $node->memberName->getFullText($node->getRoot()->getFullText()); foreach ($node->getDescendantNodes() as $child) { diff --git a/app/Parsers/VariableParser.php b/app/Parsers/VariableParser.php index ed9004e..03d175c 100644 --- a/app/Parsers/VariableParser.php +++ b/app/Parsers/VariableParser.php @@ -16,17 +16,19 @@ class VariableParser extends AbstractParser protected AbstractContext $context; /** - * Check if the variable has a object operator and + * Check if the node has a object operator and * is a last element in the string */ - private function isAutocompleting(Variable $node): bool + private function hasObjectOperator(Variable $node): bool { - return preg_match('/\$' . $node->getName() . '->;$/s', $node->getFileContents()); + $name = $node->getName(); + + return preg_match('/->' . $name . '->;$/s', $node->getFileContents()); } public function parse(Variable $node) { - if ($this->isAutocompleting($node)) { + if ($this->hasObjectOperator($node)) { $this->context->autocompleting = true; } From 1b7fe5643c1e4de370772c18563653b6b205bd79 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sun, 30 Mar 2025 12:16:07 +0000 Subject: [PATCH 4/8] fix --- app/Parsers/VariableParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Parsers/VariableParser.php b/app/Parsers/VariableParser.php index 03d175c..2de95a4 100644 --- a/app/Parsers/VariableParser.php +++ b/app/Parsers/VariableParser.php @@ -23,7 +23,7 @@ private function hasObjectOperator(Variable $node): bool { $name = $node->getName(); - return preg_match('/->' . $name . '->;$/s', $node->getFileContents()); + return preg_match('/\$' . $name . '->;$/s', $node->getFileContents()); } public function parse(Variable $node) From d6eac0e14782d325bdeeb88ddf75317ffd2298c0 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sun, 30 Mar 2025 21:12:36 +0000 Subject: [PATCH 5/8] refactoring --- app/Parser/Walker.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Parser/Walker.php b/app/Parser/Walker.php index b92f5e1..06a9d8f 100644 --- a/app/Parser/Walker.php +++ b/app/Parser/Walker.php @@ -53,9 +53,8 @@ protected function documentSkipsObjectOperator(): bool { if (count($this->sourceFile->statementList) === 1 && $this->sourceFile->statementList[0] instanceof InlineHtml) { $lastChars = substr($this->sourceFile->getFullText(), -2); - $closesWithObjectOperator = $lastChars === '->'; - return $closesWithObjectOperator; + return $lastChars === '->'; } return false; From 831df140adbcc798a21dbe9a15463c04b3e68553 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sun, 8 Jun 2025 10:06:30 +0000 Subject: [PATCH 6/8] merge upstream main --- app/Contexts/Variable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Contexts/Variable.php b/app/Contexts/Variable.php index fd38be2..2988512 100644 --- a/app/Contexts/Variable.php +++ b/app/Contexts/Variable.php @@ -4,7 +4,7 @@ class Variable extends AbstractContext { - public bool $findable = true; + public bool $isAbleToAutocomplete = true; public ?string $name = null; From 3bc56a2449132230f0d3e701baaf219d8c3aa460 Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sun, 14 Sep 2025 11:44:11 +0000 Subject: [PATCH 7/8] Add preg_quote for escape --- app/Parsers/MemberAccessExpressionParser.php | 2 +- app/Parsers/VariableParser.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Parsers/MemberAccessExpressionParser.php b/app/Parsers/MemberAccessExpressionParser.php index 923ce66..830f444 100644 --- a/app/Parsers/MemberAccessExpressionParser.php +++ b/app/Parsers/MemberAccessExpressionParser.php @@ -25,7 +25,7 @@ private function hasObjectOperator(MemberAccessExpression $node): bool { $name = $node->memberName->getFullText($node->getRoot()->getFullText()); - return preg_match('/->' . $name . '->;$/s', $node->getFileContents()); + return preg_match('/->' . preg_quote($name) . '->;$/s', $node->getFileContents()); } public function parse(MemberAccessExpression $node) diff --git a/app/Parsers/VariableParser.php b/app/Parsers/VariableParser.php index 2de95a4..2a619eb 100644 --- a/app/Parsers/VariableParser.php +++ b/app/Parsers/VariableParser.php @@ -23,7 +23,7 @@ private function hasObjectOperator(Variable $node): bool { $name = $node->getName(); - return preg_match('/\$' . $name . '->;$/s', $node->getFileContents()); + return preg_match('/\$' . preg_quote($name) . '->;$/s', $node->getFileContents()); } public function parse(Variable $node) From fbc9afeed91117206fc64780c87a4390ba2a49cb Mon Sep 17 00:00:00 2001 From: N1ebieski Date: Sun, 14 Sep 2025 11:50:24 +0000 Subject: [PATCH 8/8] Add delimeter to preg_quote --- app/Parsers/MemberAccessExpressionParser.php | 2 +- app/Parsers/VariableParser.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Parsers/MemberAccessExpressionParser.php b/app/Parsers/MemberAccessExpressionParser.php index 830f444..1c12a62 100644 --- a/app/Parsers/MemberAccessExpressionParser.php +++ b/app/Parsers/MemberAccessExpressionParser.php @@ -25,7 +25,7 @@ private function hasObjectOperator(MemberAccessExpression $node): bool { $name = $node->memberName->getFullText($node->getRoot()->getFullText()); - return preg_match('/->' . preg_quote($name) . '->;$/s', $node->getFileContents()); + return preg_match('/->' . preg_quote($name, '/') . '->;$/s', $node->getFileContents()); } public function parse(MemberAccessExpression $node) diff --git a/app/Parsers/VariableParser.php b/app/Parsers/VariableParser.php index 2a619eb..eefac7f 100644 --- a/app/Parsers/VariableParser.php +++ b/app/Parsers/VariableParser.php @@ -23,7 +23,7 @@ private function hasObjectOperator(Variable $node): bool { $name = $node->getName(); - return preg_match('/\$' . preg_quote($name) . '->;$/s', $node->getFileContents()); + return preg_match('/\$' . preg_quote($name, '/') . '->;$/s', $node->getFileContents()); } public function parse(Variable $node)