* Based on https://github.com/felixfbecker/php-language-server/blob/master/bin/php-language-server.php
* and https://github.com/felixfbecker/php-language-server/blob/master/src/LanguageServer.php (for language server protocol implementation)
*
* This is similar to Phan daemon mode, but it's possible for it to receive concurrent events, or more than one type of event.
* (in addition to file notifications, etc.)
*
* What will do in the most common case (checking for errors in a file):
*
* 0. Phan completes the parse phase, on the initial version of the codebase
* 1. Phan starts a Sabre event loop and listens for requests and responses: see http://sabre.io/event/loop/
* It registers addReadStream and addWriteStream (See ProtocolStreamReader and ProtocolStreamWriter)
* 2. Phan receives a notification that a file changed/was added/was removed
* 3. If the files are within the phan project (contains .phan directory),
* then phan removes the old parse state of removed/changed files, then adds the new parse state of changed/added files.
* 4. The main phan process (managing the event loop) fork, the fork shuts down the event loop without receiving any more events or touching the stream(will this work?)
* 5. The forked process runs the analysis.
* 6. The forked process reports the analysis result to the main process via IPC (similar to what \Phan\ForkPool does), along with the id of the request
* 7. Phan notifies the client of the new issues ("diagnostic" in the open Language Server Protocol)
* See https://github.com/Microsoft/language-server-protocol#language-server-protocol
// We analyze this url so that Phan is aware enough of the types and namespace maps to trigger "Go to definition"
// E.g. going to the definition of `Bar` in `use Foo as Bar; Bar::method();` requires parsing other statements in this file, not just the name in question.
//
// NOTE: This also ensures that we will run analysis, because of the check for analyze_request_set being non-empty
// We analyze this url so that Phan is aware enough of the types and namespace maps to trigger "Go to definition"
// E.g. going to the definition of `Bar` in `use Foo as Bar; Bar::method();` requires parsing other statements in this file, not just the name in question.
//
// NOTE: This also ensures that we will run analysis, because of the check for analyze_request_set being non-empty
// We analyze this url so that Phan is aware enough of the types and namespace maps to trigger "Go to definition"
// E.g. going to the definition of `Bar` in `use Foo as Bar; Bar::method();` requires parsing other statements in this file, not just the name in question.
//
// NOTE: This also ensures that we will run analysis, because of the check for analyze_request_set being non-empty
// TODO: (probably impractical, slow) Support "Find all references"? (We don't track this, except when checking for dead code elimination possibilities.