Merge branch 'master' into autocomplete-add-pseudo-keywords
commit
ab9d38a98d
|
@ -1,9 +1,8 @@
|
||||||
|
|
||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- '7.0'
|
- '7.0'
|
||||||
- '7.2.0RC5'
|
- '7.2'
|
||||||
|
|
||||||
git:
|
git:
|
||||||
depth: 10
|
depth: 10
|
||||||
|
|
|
@ -51,11 +51,7 @@ foreach($frameworks as $framework) {
|
||||||
$definitionResolver = new DefinitionResolver($index);
|
$definitionResolver = new DefinitionResolver($index);
|
||||||
$parser = new PhpParser\Parser();
|
$parser = new PhpParser\Parser();
|
||||||
|
|
||||||
try {
|
$document = new PhpDocument($testCaseFile, $fileContents, $index, $parser, $docBlockFactory, $definitionResolver);
|
||||||
$document = new PhpDocument($testCaseFile, $fileContents, $index, $parser, $docBlockFactory, $definitionResolver);
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "------------------------------\n";
|
echo "------------------------------\n";
|
||||||
|
|
|
@ -211,6 +211,6 @@ The project parses PHPStorm's PHP stubs to get support for PHP builtins. It re-p
|
||||||
|
|
||||||
To debug with xDebug ensure that you have this set as an environment variable
|
To debug with xDebug ensure that you have this set as an environment variable
|
||||||
|
|
||||||
COMPOSER_ALLOW_XDEBUG=1
|
PHPLS_ALLOW_XDEBUG=1
|
||||||
|
|
||||||
This tells the Language Server to not restart without XDebug if it detects that XDebug is enabled (XDebug has a high performance impact).
|
This tells the Language Server to not restart without XDebug if it detects that XDebug is enabled (XDebug has a high performance impact).
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use LanguageServer\{LanguageServer, ProtocolStreamReader, ProtocolStreamWriter};
|
use LanguageServer\{LanguageServer, ProtocolStreamReader, ProtocolStreamWriter, StderrLogger};
|
||||||
use Sabre\Event\Loop;
|
use Sabre\Event\Loop;
|
||||||
use Composer\{Factory, XdebugHandler};
|
use Composer\XdebugHandler\XdebugHandler;
|
||||||
|
|
||||||
$options = getopt('', ['tcp::', 'tcp-server::', 'memory-limit::']);
|
$options = getopt('', ['tcp::', 'tcp-server::', 'memory-limit::']);
|
||||||
|
|
||||||
|
@ -24,22 +24,27 @@ set_error_handler(function (int $severity, string $message, string $file, int $l
|
||||||
throw new \ErrorException($message, 0, $severity, $file, $line);
|
throw new \ErrorException($message, 0, $severity, $file, $line);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$logger = new StderrLogger();
|
||||||
|
|
||||||
// Only write uncaught exceptions to STDERR, not STDOUT
|
// Only write uncaught exceptions to STDERR, not STDOUT
|
||||||
set_exception_handler(function (\Throwable $e) {
|
set_exception_handler(function (\Throwable $e) use ($logger) {
|
||||||
fwrite(STDERR, (string)$e);
|
$logger->critical((string)$e);
|
||||||
});
|
});
|
||||||
|
|
||||||
@cli_set_process_title('PHP Language Server');
|
@cli_set_process_title('PHP Language Server');
|
||||||
|
|
||||||
// If XDebug is enabled, restart without it
|
// If XDebug is enabled, restart without it
|
||||||
(new XdebugHandler(Factory::createOutput()))->check();
|
$xdebugHandler = new XdebugHandler('PHPLS');
|
||||||
|
$xdebugHandler->setLogger($logger);
|
||||||
|
$xdebugHandler->check();
|
||||||
|
unset($xdebugHandler);
|
||||||
|
|
||||||
if (!empty($options['tcp'])) {
|
if (!empty($options['tcp'])) {
|
||||||
// Connect to a TCP server
|
// Connect to a TCP server
|
||||||
$address = $options['tcp'];
|
$address = $options['tcp'];
|
||||||
$socket = stream_socket_client('tcp://' . $address, $errno, $errstr);
|
$socket = stream_socket_client('tcp://' . $address, $errno, $errstr);
|
||||||
if ($socket === false) {
|
if ($socket === false) {
|
||||||
fwrite(STDERR, "Could not connect to language client. Error $errno\n$errstr");
|
$logger->critical("Could not connect to language client. Error $errno\n$errstr");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
stream_set_blocking($socket, false);
|
stream_set_blocking($socket, false);
|
||||||
|
@ -53,29 +58,30 @@ if (!empty($options['tcp'])) {
|
||||||
$address = $options['tcp-server'];
|
$address = $options['tcp-server'];
|
||||||
$tcpServer = stream_socket_server('tcp://' . $address, $errno, $errstr);
|
$tcpServer = stream_socket_server('tcp://' . $address, $errno, $errstr);
|
||||||
if ($tcpServer === false) {
|
if ($tcpServer === false) {
|
||||||
fwrite(STDERR, "Could not listen on $address. Error $errno\n$errstr");
|
$logger->critical("Could not listen on $address. Error $errno\n$errstr");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fwrite(STDOUT, "Server listening on $address\n");
|
$logger->debug("Server listening on $address");
|
||||||
if (!extension_loaded('pcntl')) {
|
$pcntlAvailable = extension_loaded('pcntl');
|
||||||
fwrite(STDERR, "PCNTL is not available. Only a single connection will be accepted\n");
|
if (!$pcntlAvailable) {
|
||||||
|
$logger->notice('PCNTL is not available. Only a single connection will be accepted');
|
||||||
}
|
}
|
||||||
while ($socket = stream_socket_accept($tcpServer, -1)) {
|
while ($socket = stream_socket_accept($tcpServer, -1)) {
|
||||||
fwrite(STDOUT, "Connection accepted\n");
|
$logger->debug('Connection accepted');
|
||||||
stream_set_blocking($socket, false);
|
stream_set_blocking($socket, false);
|
||||||
if (extension_loaded('pcntl')) {
|
if ($pcntlAvailable) {
|
||||||
// If PCNTL is available, fork a child process for the connection
|
// If PCNTL is available, fork a child process for the connection
|
||||||
// An exit notification will only terminate the child process
|
// An exit notification will only terminate the child process
|
||||||
$pid = pcntl_fork();
|
$pid = pcntl_fork();
|
||||||
if ($pid === -1) {
|
if ($pid === -1) {
|
||||||
fwrite(STDERR, "Could not fork\n");
|
$logger->critical('Could not fork');
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if ($pid === 0) {
|
} else if ($pid === 0) {
|
||||||
// Child process
|
// Child process
|
||||||
$reader = new ProtocolStreamReader($socket);
|
$reader = new ProtocolStreamReader($socket);
|
||||||
$writer = new ProtocolStreamWriter($socket);
|
$writer = new ProtocolStreamWriter($socket);
|
||||||
$reader->on('close', function () {
|
$reader->on('close', function () use ($logger) {
|
||||||
fwrite(STDOUT, "Connection closed\n");
|
$logger->debug('Connection closed');
|
||||||
});
|
});
|
||||||
$ls = new LanguageServer($reader, $writer);
|
$ls = new LanguageServer($reader, $writer);
|
||||||
Loop\run();
|
Loop\run();
|
||||||
|
@ -94,6 +100,7 @@ if (!empty($options['tcp'])) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Use STDIO
|
// Use STDIO
|
||||||
|
$logger->debug('Listening on STDIN');
|
||||||
stream_set_blocking(STDIN, false);
|
stream_set_blocking(STDIN, false);
|
||||||
$ls = new LanguageServer(
|
$ls = new LanguageServer(
|
||||||
new ProtocolStreamReader(STDIN),
|
new ProtocolStreamReader(STDIN),
|
||||||
|
|
|
@ -22,12 +22,13 @@
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^7.0",
|
"php": "^7.0",
|
||||||
"composer/composer": "^1.3",
|
"composer/xdebug-handler": "^1.0",
|
||||||
"felixfbecker/advanced-json-rpc": "^3.0.0",
|
"felixfbecker/advanced-json-rpc": "^3.0.0",
|
||||||
"jetbrains/phpstorm-stubs": "dev-master",
|
"jetbrains/phpstorm-stubs": "dev-master",
|
||||||
"microsoft/tolerant-php-parser": "0.0.*",
|
"microsoft/tolerant-php-parser": "0.0.*",
|
||||||
"netresearch/jsonmapper": "^1.0",
|
"netresearch/jsonmapper": "^1.0",
|
||||||
"phpdocumentor/reflection-docblock": "^4.0.0",
|
"phpdocumentor/reflection-docblock": "^4.0.0",
|
||||||
|
"psr/log": "^1.0",
|
||||||
"sabre/event": "^5.0",
|
"sabre/event": "^5.0",
|
||||||
"sabre/uri": "^2.0",
|
"sabre/uri": "^2.0",
|
||||||
"webmozart/glob": "^4.1",
|
"webmozart/glob": "^4.1",
|
||||||
|
|
|
@ -10,9 +10,6 @@ collectors:
|
||||||
commit_message_prefix: "chore: "
|
commit_message_prefix: "chore: "
|
||||||
- type: js-npm
|
- type: js-npm
|
||||||
path: /
|
path: /
|
||||||
settings:
|
|
||||||
dist_tags:
|
|
||||||
semantic-release: next
|
|
||||||
actors:
|
actors:
|
||||||
- type: js-npm
|
- type: js-npm
|
||||||
versions: "Y.0.0"
|
versions: "Y.0.0"
|
||||||
|
|
|
@ -3,7 +3,6 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer\Cache;
|
namespace LanguageServer\Cache;
|
||||||
|
|
||||||
use LanguageServer\LanguageClient;
|
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types = 1);
|
||||||
namespace LanguageServer\Client;
|
namespace LanguageServer\Client;
|
||||||
|
|
||||||
use LanguageServer\ClientHandler;
|
use LanguageServer\ClientHandler;
|
||||||
use LanguageServer\Protocol\{Message, TextDocumentItem, TextDocumentIdentifier};
|
use LanguageServer\Protocol\{TextDocumentItem, TextDocumentIdentifier};
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
use JsonMapper;
|
use JsonMapper;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types = 1);
|
||||||
namespace LanguageServer\Client;
|
namespace LanguageServer\Client;
|
||||||
|
|
||||||
use LanguageServer\ClientHandler;
|
use LanguageServer\ClientHandler;
|
||||||
use LanguageServer\Protocol\Message;
|
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types = 1);
|
||||||
namespace LanguageServer\Client;
|
namespace LanguageServer\Client;
|
||||||
|
|
||||||
use LanguageServer\ClientHandler;
|
use LanguageServer\ClientHandler;
|
||||||
use LanguageServer\Protocol\Message;
|
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,7 +6,6 @@ namespace LanguageServer;
|
||||||
use LanguageServer\Index\ReadableIndex;
|
use LanguageServer\Index\ReadableIndex;
|
||||||
use phpDocumentor\Reflection\{Types, Type, Fqsen, TypeResolver};
|
use phpDocumentor\Reflection\{Types, Type, Fqsen, TypeResolver};
|
||||||
use LanguageServer\Protocol\SymbolInformation;
|
use LanguageServer\Protocol\SymbolInformation;
|
||||||
use Exception;
|
|
||||||
use Generator;
|
use Generator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +68,7 @@ class Definition
|
||||||
public $canBeInstantiated;
|
public $canBeInstantiated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Protocol\SymbolInformation
|
* @var SymbolInformation
|
||||||
*/
|
*/
|
||||||
public $symbolInformation;
|
public $symbolInformation;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
namespace LanguageServer\FqnUtilities;
|
namespace LanguageServer\FqnUtilities;
|
||||||
|
|
||||||
use phpDocumentor\Reflection\{Type, Types};
|
use phpDocumentor\Reflection\{Type, Types};
|
||||||
use Microsoft\PhpParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all possible FQNs in a type
|
* Returns all possible FQNs in a type
|
||||||
|
|
|
@ -6,10 +6,8 @@ namespace LanguageServer;
|
||||||
use LanguageServer\Cache\Cache;
|
use LanguageServer\Cache\Cache;
|
||||||
use LanguageServer\FilesFinder\FilesFinder;
|
use LanguageServer\FilesFinder\FilesFinder;
|
||||||
use LanguageServer\Index\{DependenciesIndex, Index};
|
use LanguageServer\Index\{DependenciesIndex, Index};
|
||||||
use LanguageServer\Protocol\Message;
|
|
||||||
use LanguageServer\Protocol\MessageType;
|
use LanguageServer\Protocol\MessageType;
|
||||||
use Webmozart\PathUtil\Path;
|
use Webmozart\PathUtil\Path;
|
||||||
use Composer\Semver\VersionParser;
|
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
use function Sabre\Event\coroutine;
|
use function Sabre\Event\coroutine;
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,9 @@ class PhpDocument
|
||||||
|
|
||||||
// Register this document on the project for references
|
// Register this document on the project for references
|
||||||
foreach ($this->referenceNodes as $fqn => $nodes) {
|
foreach ($this->referenceNodes as $fqn => $nodes) {
|
||||||
$this->index->addReferenceUri($fqn, $this->uri);
|
// Cast the key to string. If (string)'2' is set as an array index, it will read out as (int)2. We must
|
||||||
|
// deal with incorrect code, so this is a valid scenario.
|
||||||
|
$this->index->addReferenceUri((string)$fqn, $this->uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sourceFileNode = $treeAnalyzer->getSourceFileNode();
|
$this->sourceFileNode = $treeAnalyzer->getSourceFileNode();
|
||||||
|
|
|
@ -4,7 +4,6 @@ namespace LanguageServer\Protocol;
|
||||||
|
|
||||||
use Microsoft\PhpParser;
|
use Microsoft\PhpParser;
|
||||||
use Microsoft\PhpParser\Node;
|
use Microsoft\PhpParser\Node;
|
||||||
use Exception;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents information about programming constructs like variables, classes,
|
* Represents information about programming constructs like variables, classes,
|
||||||
|
|
|
@ -8,7 +8,6 @@ use Sabre\Event\{
|
||||||
Loop,
|
Loop,
|
||||||
Promise
|
Promise
|
||||||
};
|
};
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
class ProtocolStreamWriter implements ProtocolWriter
|
class ProtocolStreamWriter implements ProtocolWriter
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,6 @@ use LanguageServer\Protocol\{
|
||||||
VersionedTextDocumentIdentifier,
|
VersionedTextDocumentIdentifier,
|
||||||
CompletionContext
|
CompletionContext
|
||||||
};
|
};
|
||||||
use Microsoft\PhpParser;
|
|
||||||
use Microsoft\PhpParser\Node;
|
use Microsoft\PhpParser\Node;
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
use Sabre\Uri;
|
use Sabre\Uri;
|
||||||
|
|
|
@ -3,18 +3,16 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer\Server;
|
namespace LanguageServer\Server;
|
||||||
|
|
||||||
use LanguageServer\{LanguageClient, Project, PhpDocumentLoader};
|
use LanguageServer\{LanguageClient, PhpDocumentLoader};
|
||||||
use LanguageServer\Index\{ProjectIndex, DependenciesIndex, Index};
|
use LanguageServer\Index\{ProjectIndex, DependenciesIndex, Index};
|
||||||
use LanguageServer\Protocol\{
|
use LanguageServer\Protocol\{
|
||||||
FileChangeType,
|
FileChangeType,
|
||||||
FileEvent,
|
FileEvent,
|
||||||
SymbolInformation,
|
SymbolInformation,
|
||||||
SymbolDescriptor,
|
SymbolDescriptor,
|
||||||
PackageDescriptor,
|
|
||||||
ReferenceInformation,
|
ReferenceInformation,
|
||||||
DependencyReference,
|
DependencyReference,
|
||||||
Location,
|
Location
|
||||||
MessageType
|
|
||||||
};
|
};
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
use function Sabre\Event\coroutine;
|
use function Sabre\Event\coroutine;
|
||||||
|
|
|
@ -7,10 +7,8 @@ use LanguageServer\Index\ReadableIndex;
|
||||||
use LanguageServer\Protocol\{
|
use LanguageServer\Protocol\{
|
||||||
Position,
|
Position,
|
||||||
SignatureHelp,
|
SignatureHelp,
|
||||||
SignatureInformation,
|
|
||||||
ParameterInformation
|
ParameterInformation
|
||||||
};
|
};
|
||||||
use Microsoft\PhpParser;
|
|
||||||
use Microsoft\PhpParser\Node;
|
use Microsoft\PhpParser\Node;
|
||||||
use Sabre\Event\Promise;
|
use Sabre\Event\Promise;
|
||||||
use function Sabre\Event\coroutine;
|
use function Sabre\Event\coroutine;
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace LanguageServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple Logger that logs to STDERR
|
||||||
|
*/
|
||||||
|
class StderrLogger extends \Psr\Log\AbstractLogger implements \Psr\Log\LoggerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Logs with an arbitrary level.
|
||||||
|
*
|
||||||
|
* @param mixed $level
|
||||||
|
* @param string $message
|
||||||
|
* @param array $context
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function log($level, $message, array $context = array())
|
||||||
|
{
|
||||||
|
$contextStr = empty($context) ? '' : ' ' . \json_encode($context, \JSON_UNESCAPED_SLASHES);
|
||||||
|
\fwrite(\STDERR, \str_pad(\strtoupper((string)$level), 10) . $message . $contextStr . \PHP_EOL);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,10 +3,8 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace LanguageServer;
|
namespace LanguageServer;
|
||||||
|
|
||||||
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, TextEdit};
|
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position};
|
||||||
use LanguageServer\Index\Index;
|
|
||||||
use phpDocumentor\Reflection\DocBlockFactory;
|
use phpDocumentor\Reflection\DocBlockFactory;
|
||||||
use Sabre\Uri;
|
|
||||||
use Microsoft\PhpParser;
|
use Microsoft\PhpParser;
|
||||||
use Microsoft\PhpParser\Node;
|
use Microsoft\PhpParser\Node;
|
||||||
use Microsoft\PhpParser\Token;
|
use Microsoft\PhpParser\Token;
|
||||||
|
|
Loading…
Reference in New Issue