|
1 | 1 | <?php
|
2 | 2 |
|
3 |
| -use LanguageServer\{LanguageServer, ProtocolStreamReader, ProtocolStreamWriter}; |
| 3 | +use LanguageServer\{LanguageServer, ProtocolStreamReader, ProtocolStreamWriter, StderrLogger}; |
4 | 4 | use Sabre\Event\Loop;
|
5 |
| -use Composer\{Factory, XdebugHandler}; |
| 5 | +use Composer\XdebugHandler\XdebugHandler; |
6 | 6 |
|
7 | 7 | $options = getopt('', ['tcp::', 'tcp-server::', 'memory-limit::']);
|
8 | 8 |
|
|
24 | 24 | throw new \ErrorException($message, 0, $severity, $file, $line);
|
25 | 25 | });
|
26 | 26 |
|
| 27 | +$logger = new StderrLogger(); |
| 28 | + |
27 | 29 | // Only write uncaught exceptions to STDERR, not STDOUT
|
28 |
| -set_exception_handler(function (\Throwable $e) { |
29 |
| - fwrite(STDERR, (string)$e); |
| 30 | +set_exception_handler(function (\Throwable $e) use ($logger) { |
| 31 | + $logger->critical((string)$e); |
30 | 32 | });
|
31 | 33 |
|
32 | 34 | @cli_set_process_title('PHP Language Server');
|
33 | 35 |
|
34 | 36 | // If XDebug is enabled, restart without it
|
35 |
| -(new XdebugHandler(Factory::createOutput()))->check(); |
| 37 | +$xdebugHandler = new XdebugHandler('PHPLS'); |
| 38 | +$xdebugHandler->setLogger($logger); |
| 39 | +$xdebugHandler->check(); |
| 40 | +unset($xdebugHandler); |
36 | 41 |
|
37 | 42 | if (!empty($options['tcp'])) {
|
38 | 43 | // Connect to a TCP server
|
39 | 44 | $address = $options['tcp'];
|
40 | 45 | $socket = stream_socket_client('tcp://' . $address, $errno, $errstr);
|
41 | 46 | if ($socket === false) {
|
42 |
| - fwrite(STDERR, "Could not connect to language client. Error $errno\n$errstr"); |
| 47 | + $logger->critical("Could not connect to language client. Error $errno\n$errstr"); |
43 | 48 | exit(1);
|
44 | 49 | }
|
45 | 50 | stream_set_blocking($socket, false);
|
|
53 | 58 | $address = $options['tcp-server'];
|
54 | 59 | $tcpServer = stream_socket_server('tcp://' . $address, $errno, $errstr);
|
55 | 60 | if ($tcpServer === false) {
|
56 |
| - fwrite(STDERR, "Could not listen on $address. Error $errno\n$errstr"); |
| 61 | + $logger->critical("Could not listen on $address. Error $errno\n$errstr"); |
57 | 62 | exit(1);
|
58 | 63 | }
|
59 |
| - fwrite(STDOUT, "Server listening on $address\n"); |
60 |
| - if (!extension_loaded('pcntl')) { |
61 |
| - fwrite(STDERR, "PCNTL is not available. Only a single connection will be accepted\n"); |
| 64 | + $logger->debug("Server listening on $address"); |
| 65 | + $pcntlAvailable = extension_loaded('pcntl'); |
| 66 | + if (!$pcntlAvailable) { |
| 67 | + $logger->notice('PCNTL is not available. Only a single connection will be accepted'); |
62 | 68 | }
|
63 | 69 | while ($socket = stream_socket_accept($tcpServer, -1)) {
|
64 |
| - fwrite(STDOUT, "Connection accepted\n"); |
| 70 | + $logger->debug('Connection accepted'); |
65 | 71 | stream_set_blocking($socket, false);
|
66 |
| - if (extension_loaded('pcntl')) { |
| 72 | + if ($pcntlAvailable) { |
67 | 73 | // If PCNTL is available, fork a child process for the connection
|
68 | 74 | // An exit notification will only terminate the child process
|
69 | 75 | $pid = pcntl_fork();
|
70 | 76 | if ($pid === -1) {
|
71 |
| - fwrite(STDERR, "Could not fork\n"); |
| 77 | + $logger->critical('Could not fork'); |
72 | 78 | exit(1);
|
73 | 79 | } else if ($pid === 0) {
|
74 | 80 | // Child process
|
75 | 81 | $reader = new ProtocolStreamReader($socket);
|
76 | 82 | $writer = new ProtocolStreamWriter($socket);
|
77 |
| - $reader->on('close', function () { |
78 |
| - fwrite(STDOUT, "Connection closed\n"); |
| 83 | + $reader->on('close', function () use ($logger) { |
| 84 | + $logger->debug('Connection closed'); |
79 | 85 | });
|
80 | 86 | $ls = new LanguageServer($reader, $writer);
|
81 | 87 | Loop\run();
|
|
94 | 100 | }
|
95 | 101 | } else {
|
96 | 102 | // Use STDIO
|
| 103 | + $logger->debug('Listening on STDIN'); |
97 | 104 | stream_set_blocking(STDIN, false);
|
98 | 105 | $ls = new LanguageServer(
|
99 | 106 | new ProtocolStreamReader(STDIN),
|
|
0 commit comments