mirror of
https://gitlab.com/signalytic/client-external/streamline/streamline-emr.git
synced 2026-09-11 18:51:31 +00:00
resolved conflicts
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Lexer\TokenEmulator;
|
||||
|
||||
use PhpParser\PhpVersion;
|
||||
use PhpParser\Token;
|
||||
|
||||
final class AsymmetricVisibilityTokenEmulator extends TokenEmulator {
|
||||
public function getPhpVersion(): PhpVersion {
|
||||
return PhpVersion::fromComponents(8, 4);
|
||||
}
|
||||
public function isEmulationNeeded(string $code): bool {
|
||||
$code = strtolower($code);
|
||||
return strpos($code, 'public(set)') !== false ||
|
||||
strpos($code, 'protected(set)') !== false ||
|
||||
strpos($code, 'private(set)') !== false;
|
||||
}
|
||||
|
||||
public function emulate(string $code, array $tokens): array {
|
||||
$map = [
|
||||
\T_PUBLIC => \T_PUBLIC_SET,
|
||||
\T_PROTECTED => \T_PROTECTED_SET,
|
||||
\T_PRIVATE => \T_PRIVATE_SET,
|
||||
];
|
||||
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
|
||||
$token = $tokens[$i];
|
||||
if (isset($map[$token->id]) && $i + 3 < $c && $tokens[$i + 1]->text === '(' &&
|
||||
$tokens[$i + 2]->id === \T_STRING && \strtolower($tokens[$i + 2]->text) === 'set' &&
|
||||
$tokens[$i + 3]->text === ')' &&
|
||||
$this->isKeywordContext($tokens, $i)
|
||||
) {
|
||||
array_splice($tokens, $i, 4, [
|
||||
new Token(
|
||||
$map[$token->id], $token->text . '(' . $tokens[$i + 2]->text . ')',
|
||||
$token->line, $token->pos),
|
||||
]);
|
||||
$c -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
public function reverseEmulate(string $code, array $tokens): array {
|
||||
$reverseMap = [
|
||||
\T_PUBLIC_SET => \T_PUBLIC,
|
||||
\T_PROTECTED_SET => \T_PROTECTED,
|
||||
\T_PRIVATE_SET => \T_PRIVATE,
|
||||
];
|
||||
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
|
||||
$token = $tokens[$i];
|
||||
if (isset($reverseMap[$token->id]) &&
|
||||
\preg_match('/(public|protected|private)\((set)\)/i', $token->text, $matches)
|
||||
) {
|
||||
[, $modifier, $set] = $matches;
|
||||
$modifierLen = \strlen($modifier);
|
||||
array_splice($tokens, $i, 1, [
|
||||
new Token($reverseMap[$token->id], $modifier, $token->line, $token->pos),
|
||||
new Token(\ord('('), '(', $token->line, $token->pos + $modifierLen),
|
||||
new Token(\T_STRING, $set, $token->line, $token->pos + $modifierLen + 1),
|
||||
new Token(\ord(')'), ')', $token->line, $token->pos + $modifierLen + 4),
|
||||
]);
|
||||
$i += 3;
|
||||
$c += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/** @param Token[] $tokens */
|
||||
protected function isKeywordContext(array $tokens, int $pos): bool {
|
||||
$prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
|
||||
if ($prevToken === null) {
|
||||
return false;
|
||||
}
|
||||
return $prevToken->id !== \T_OBJECT_OPERATOR
|
||||
&& $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
|
||||
}
|
||||
|
||||
/** @param Token[] $tokens */
|
||||
private function getPreviousNonSpaceToken(array $tokens, int $start): ?Token {
|
||||
for ($i = $start - 1; $i >= 0; --$i) {
|
||||
if ($tokens[$i]->id === T_WHITESPACE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $tokens[$i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Lexer\TokenEmulator;
|
||||
|
||||
use PhpParser\PhpVersion;
|
||||
|
||||
final class PropertyTokenEmulator extends KeywordEmulator {
|
||||
public function getPhpVersion(): PhpVersion {
|
||||
return PhpVersion::fromComponents(8, 4);
|
||||
}
|
||||
|
||||
public function getKeywordString(): string {
|
||||
return '__property__';
|
||||
}
|
||||
|
||||
public function getKeywordToken(): int {
|
||||
return \T_PROPERTY_C;
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node;
|
||||
|
||||
use PhpParser\Modifiers;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PhpParser\NodeAbstract;
|
||||
|
||||
class PropertyHook extends NodeAbstract implements FunctionLike {
|
||||
/** @var AttributeGroup[] PHP attribute groups */
|
||||
public array $attrGroups;
|
||||
/** @var int Modifiers */
|
||||
public int $flags;
|
||||
/** @var bool Whether hook returns by reference */
|
||||
public bool $byRef;
|
||||
/** @var Identifier Hook name */
|
||||
public Identifier $name;
|
||||
/** @var Param[] Parameters */
|
||||
public array $params;
|
||||
/** @var null|Expr|Stmt[] Hook body */
|
||||
public $body;
|
||||
|
||||
/**
|
||||
* Constructs a property hook node.
|
||||
*
|
||||
* @param string|Identifier $name Hook name
|
||||
* @param null|Expr|Stmt[] $body Hook body
|
||||
* @param array{
|
||||
* flags?: int,
|
||||
* byRef?: bool,
|
||||
* params?: Param[],
|
||||
* attrGroups?: AttributeGroup[],
|
||||
* } $subNodes Array of the following optional subnodes:
|
||||
* 'flags => 0 : Flags
|
||||
* 'byRef' => false : Whether hook returns by reference
|
||||
* 'params' => array(): Parameters
|
||||
* 'attrGroups' => array(): PHP attribute groups
|
||||
* @param array<string, mixed> $attributes Additional attributes
|
||||
*/
|
||||
public function __construct($name, $body, array $subNodes = [], array $attributes = []) {
|
||||
$this->attributes = $attributes;
|
||||
$this->name = \is_string($name) ? new Identifier($name) : $name;
|
||||
$this->body = $body;
|
||||
$this->flags = $subNodes['flags'] ?? 0;
|
||||
$this->byRef = $subNodes['byRef'] ?? false;
|
||||
$this->params = $subNodes['params'] ?? [];
|
||||
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||
}
|
||||
|
||||
public function returnsByRef(): bool {
|
||||
return $this->byRef;
|
||||
}
|
||||
|
||||
public function getParams(): array {
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
public function getReturnType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the property hook is final.
|
||||
*/
|
||||
public function isFinal(): bool {
|
||||
return (bool) ($this->flags & Modifiers::FINAL);
|
||||
}
|
||||
|
||||
public function getStmts(): ?array {
|
||||
if ($this->body instanceof Expr) {
|
||||
$name = $this->name->toLowerString();
|
||||
if ($name === 'get') {
|
||||
return [new Return_($this->body)];
|
||||
}
|
||||
if ($name === 'set') {
|
||||
if (!$this->hasAttribute('propertyName')) {
|
||||
throw new \LogicException(
|
||||
'Can only use getStmts() on a "set" hook if the "propertyName" attribute is set');
|
||||
}
|
||||
|
||||
$propName = $this->getAttribute('propertyName');
|
||||
$prop = new PropertyFetch(new Variable('this'), (string) $propName);
|
||||
return [new Expression(new Assign($prop, $this->body))];
|
||||
}
|
||||
throw new \LogicException('Unknown property hook "' . $name . '"');
|
||||
}
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
public function getAttrGroups(): array {
|
||||
return $this->attrGroups;
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return 'PropertyHook';
|
||||
}
|
||||
|
||||
public function getSubNodeNames(): array {
|
||||
return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'body'];
|
||||
}
|
||||
}
|
||||
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Scalar\MagicConst;
|
||||
|
||||
use PhpParser\Node\Scalar\MagicConst;
|
||||
|
||||
class Property extends MagicConst {
|
||||
public function getName(): string {
|
||||
return '__PROPERTY__';
|
||||
}
|
||||
|
||||
public function getType(): string {
|
||||
return 'Scalar_MagicConst_Property';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user