Skip to content

Commit

Permalink
Add InlineValue objects to generated LSP (#19)
Browse files Browse the repository at this point in the history
* Add protocol.inlineValue.d.ts, handle literal types.

* Add Inline objects.

* Improved class generation.
  • Loading branch information
zobo authored Apr 4, 2024
1 parent 065fc70 commit c05285e
Show file tree
Hide file tree
Showing 15 changed files with 664 additions and 14 deletions.
15 changes: 13 additions & 2 deletions src/InlayHintOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,31 @@
use RuntimeException;

/**
* Mixins (implemented TS interfaces): WorkDoneProgressOptions, array
* Mixins (implemented TS interfaces): WorkDoneProgressOptions
*/
class InlayHintOptions
{
/**
* The server provides support to resolve additional
* information for an inlay hint item.
*
* @var bool|null
*/
public $resolveProvider;

/**
*
* @var bool|null
*/
public $workDoneProgress;

/**
* @param bool|null $resolveProvider
* @param bool|null $workDoneProgress
*/
public function __construct(?bool $workDoneProgress = null)
public function __construct(?bool $resolveProvider = null, ?bool $workDoneProgress = null)
{
$this->resolveProvider = $resolveProvider;
$this->workDoneProgress = $workDoneProgress;
}

Expand All @@ -32,6 +42,7 @@ public function __construct(?bool $workDoneProgress = null)
public static function fromArray(array $array, bool $allowUnknownKeys = false)
{
$map = [
'resolveProvider' => ['names' => [], 'iterable' => false],
'workDoneProgress' => ['names' => [], 'iterable' => false],
];

Expand Down
24 changes: 22 additions & 2 deletions src/InlayHintParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@
use RuntimeException;

/**
* Mixins (implemented TS interfaces): WorkDoneProgressParams, array
* Mixins (implemented TS interfaces): WorkDoneProgressParams
*/
class InlayHintParams
{
/**
* The text document.
*
* @var TextDocumentIdentifier
*/
public $textDocument;

/**
* The document range for which inlay hints should be computed.
*
* @var Range
*/
public $range;

/**
* An optional token that a server can use to report work done progress.
*
Expand All @@ -19,10 +33,14 @@ class InlayHintParams
public $workDoneToken;

/**
* @param TextDocumentIdentifier $textDocument
* @param Range $range
* @param int|string|null $workDoneToken
*/
public function __construct($workDoneToken = null)
public function __construct(TextDocumentIdentifier $textDocument, Range $range, $workDoneToken = null)
{
$this->textDocument = $textDocument;
$this->range = $range;
$this->workDoneToken = $workDoneToken;
}

Expand All @@ -33,6 +51,8 @@ public function __construct($workDoneToken = null)
public static function fromArray(array $array, bool $allowUnknownKeys = false)
{
$map = [
'textDocument' => ['names' => [TextDocumentIdentifier::class], 'iterable' => false],
'range' => ['names' => [Range::class], 'iterable' => false],
'workDoneToken' => ['names' => [], 'iterable' => false],
];

Expand Down
110 changes: 110 additions & 0 deletions src/InlineValueEvaluatableExpression.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<?php // Auto-generated from vscode-languageserver-protocol (typescript)

namespace Phpactor\LanguageServerProtocol;

use DTL\Invoke\Invoke;
use Exception;
use RuntimeException;

class InlineValueEvaluatableExpression
{
/**
* The document range for which the inline value applies.
* The range is used to extract the evaluatable expression from the underlying document.
*
* @var Range
*/
public $range;

/**
* If specified the expression overrides the extracted expression.
*
* @var string|null
*/
public $expression;

/**
* @param Range $range
* @param string|null $expression
*/
public function __construct(Range $range, ?string $expression = null)
{
$this->range = $range;
$this->expression = $expression;
}

/**
* @param array<string,mixed> $array
* @return self
*/
public static function fromArray(array $array, bool $allowUnknownKeys = false)
{
$map = [
'range' => ['names' => [Range::class], 'iterable' => false],
'expression' => ['names' => [], 'iterable' => false],
];

foreach ($array as $key => &$value) {
if (!isset($map[$key])) {
if ($allowUnknownKeys) {
unset($array[$key]);
continue;
}

throw new RuntimeException(sprintf(
'Parameter "%s" on class "%s" not known, known parameters: "%s"',
$key,
self::class,
implode('", "', array_keys($map))
));
}

// from here we only care about arrays that can be transformed into
// objects
if (!is_array($value)) {
continue;
}

if (empty($map[$key]['names'])) {
continue;
}

if ($map[$key]['iterable']) {
$value = array_map(function ($object) use ($map, $key, $allowUnknownKeys) {
if (!is_array($object)) {
return $object;
}

return self::invokeFromNames($map[$key]['names'], $object, $allowUnknownKeys) ?: $object;
}, $value);
continue;
}

$names = $map[$key]['names'];
$value = self::invokeFromNames($names, $value, $allowUnknownKeys) ?: $value;
}

return Invoke::new(self::class, $array);
}

/**
* @param array<string> $classNames
* @param array<string,mixed> $object
*/
private static function invokeFromNames(array $classNames, array $object, bool $allowUnknownKeys): ?object
{
$lastException = null;
foreach ($classNames as $className) {
try {
// @phpstan-ignore-next-line
return call_user_func_array($className . '::fromArray', [$object, $allowUnknownKeys]);
} catch (Exception $exception) {
$lastException = $exception;
continue;
}
}

throw $lastException;
}

}
133 changes: 133 additions & 0 deletions src/InlineValueParams.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php // Auto-generated from vscode-languageserver-protocol (typescript)

namespace Phpactor\LanguageServerProtocol;

use DTL\Invoke\Invoke;
use Exception;
use RuntimeException;

/**
* Mixins (implemented TS interfaces): WorkDoneProgressParams
*/
class InlineValueParams
{
/**
* The text document.
*
* @var TextDocumentIdentifier
*/
public $textDocument;

/**
* The document range for which inline values should be computed.
*
* @var Range
*/
public $range;

/**
* Additional information about the context in which inline values were
* requested.
*
* @var array{frameId:int,stoppedLocation:Range}
*/
public $context;

/**
* An optional token that a server can use to report work done progress.
*
* @var int|string|null
*/
public $workDoneToken;

/**
* @param TextDocumentIdentifier $textDocument
* @param Range $range
* @param array{frameId:int,stoppedLocation:Range} $context
* @param int|string|null $workDoneToken
*/
public function __construct(TextDocumentIdentifier $textDocument, Range $range, array $context, $workDoneToken = null)
{
$this->textDocument = $textDocument;
$this->range = $range;
$this->context = $context;
$this->workDoneToken = $workDoneToken;
}

/**
* @param array<string,mixed> $array
* @return self
*/
public static function fromArray(array $array, bool $allowUnknownKeys = false)
{
$map = [
'textDocument' => ['names' => [TextDocumentIdentifier::class], 'iterable' => false],
'range' => ['names' => [Range::class], 'iterable' => false],
'context' => ['names' => [], 'iterable' => false],
'workDoneToken' => ['names' => [], 'iterable' => false],
];

foreach ($array as $key => &$value) {
if (!isset($map[$key])) {
if ($allowUnknownKeys) {
unset($array[$key]);
continue;
}

throw new RuntimeException(sprintf(
'Parameter "%s" on class "%s" not known, known parameters: "%s"',
$key,
self::class,
implode('", "', array_keys($map))
));
}

// from here we only care about arrays that can be transformed into
// objects
if (!is_array($value)) {
continue;
}

if (empty($map[$key]['names'])) {
continue;
}

if ($map[$key]['iterable']) {
$value = array_map(function ($object) use ($map, $key, $allowUnknownKeys) {
if (!is_array($object)) {
return $object;
}

return self::invokeFromNames($map[$key]['names'], $object, $allowUnknownKeys) ?: $object;
}, $value);
continue;
}

$names = $map[$key]['names'];
$value = self::invokeFromNames($names, $value, $allowUnknownKeys) ?: $value;
}

return Invoke::new(self::class, $array);
}

/**
* @param array<string> $classNames
* @param array<string,mixed> $object
*/
private static function invokeFromNames(array $classNames, array $object, bool $allowUnknownKeys): ?object
{
$lastException = null;
foreach ($classNames as $className) {
try {
// @phpstan-ignore-next-line
return call_user_func_array($className . '::fromArray', [$object, $allowUnknownKeys]);
} catch (Exception $exception) {
$lastException = $exception;
continue;
}
}

throw $lastException;
}

}
8 changes: 8 additions & 0 deletions src/InlineValueRefreshRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php // Auto-generated from vscode-languageserver-protocol (typescript)

namespace Phpactor\LanguageServerProtocol;

interface InlineValueRefreshRequest
{
public const METHOD = 'workspace/inlineValue/refresh';
}
Loading

0 comments on commit c05285e

Please sign in to comment.