Skip to content

Commit

Permalink
Implement IDE option to analyze only on save; use TCP instead of stdio
Browse files Browse the repository at this point in the history
Also, fix the CLI flags for TCP.
The language server **client** is the owner of the TCP port.

stdio may hang on large responses, so use TCP instead.
I'm not aware of the details.

Update Phan
- fix a bug where the analysis worker forked off by the main
  language server process might read additional subsequent sent by the
  language client (intended for the main server process)
  • Loading branch information
TysonAndre committed Feb 8, 2018
1 parent b00a372 commit 156c40d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 33 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,27 @@ And then point to that phan installation:

## Release History

### 0.0.8 (2018-02-04)
### 0.0.10 (2018-02-07)

- Add an option `phan.connectToServerWithStdio` to allow clients to continue to use stdio to communicate with the Phan language server. ([Issue #8](https://github.com/TysonAndre/vscode-php-phan/issues/8))
- Update Phan.

Fix an edge case where the forked language server analysis worker might read a request
intended for the main process of the Phan language server (this could happen if multiple requests were sent before Phan could respond)

### 0.0.9 (2018-02-04)

- Bump Phan version in composer.lock from 0.10.3 to 0.10.4-dev
See [Phan's NEWS](https://raw.githubusercontent.com/phan/phan/fbb3be4fd6953fa9a56eb765e5c6d07d538640cb/NEWS) for more details

- Phan supports analyzing `array<int,T>` and `array<string,T>` syntax in PHPDoc and in Phan's internal type system.
- Phan supports analyzing `array<int,T>` and `array<string,T>` syntax in PHPDoc and in Phan's internal type system.
(Previously, Phan would internally represent generic arrays as `T[]` (i.e. wouldn't track key types))
- Various improvements and bug fixes.
- Add a new VSCode configuration option `phan.analyzeOnlyOnSave` (off by default). (#6)
If you set this to true, Phan will analyze the file only when you open/save the file (And not while editing or typing).
This is useful on large projects or PHP files.
- Change the default transport for communicating with the Phan language server from stdio to TCP.
(Stdio may block when large requests/responses are sent)

### 0.0.8 (2018-01-20)

Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"license": "MIT",
"private": true,
"preview": false,
"version": "0.0.9",
"version": "0.0.10",
"engines": {
"vscode": "^1.16.0",
"os": [
Expand Down Expand Up @@ -51,11 +51,11 @@
"devDependencies": {
"@types/mocha": "^2.2.48",
"@types/mz": "0.0.31",
"@types/node": "^8.0.24",
"@types/node": "^8.9.0",
"@types/semver": "^5.5.0",
"tslint": "^5.7.0",
"typescript": "^2.7.1",
"vsce": "^1.36.1",
"vsce": "^1.36.2",
"vscode": "^1.1.0"
},
"dependencies": {
Expand Down Expand Up @@ -130,6 +130,14 @@
"description": "The memory limit of Phan (the php language server) in bytes. Format: Number[K|M|G] (e.g. \"1G\" or \"200M\"). Set to null for no memory limit (default). (Modifying requires restart)",
"pattern": "^\\d+[KMG]?$"
},
"phan.connectToServerWithStdio": {
"type": [
"boolean",
"null"
],
"default": false,
"description": "If this is set to true, this VSCode extension will use stdio instead of the default of TCP to communicate with the Phan server. Enabling this may help if you have issues getting Phan to analyze your project. (Modifying requires restart)"
},
"phan.additionalCLIFlags": {
"type": [
"array"
Expand Down
45 changes: 26 additions & 19 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
const useFallbackParser = conf.get<boolean>('useFallbackParser');
const analyzeOnlyOnSave = conf.get<boolean>('analyzeOnlyOnSave');
const memoryLimit = conf.get<string>('memoryLimit') || null;
const connectToServerWithStdio = conf.get<boolean>('connectToServerWithStdio');
const additionalCLIFlags = conf.get<string[]>('additionalCLIFlags') || [];
const quick = conf.get<boolean>('quick');
let analyzedFileExtensions: string[] = conf.get<string[]>('analyzedFileExtensions') || ['php'];
Expand Down Expand Up @@ -222,28 +223,11 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
}

const serverOptions = () => new Promise<ChildProcess | StreamInfo>((resolve, reject) => {
// NOTE: Phan isn't going to work on win32, unless we use linux subsystem (Haven't tried) or docker

// Use a TCP socket because of problems with blocking STDIO
// stdio locks up for large responses
// (based on https://github.com/felixfbecker/vscode-php-intellisense/commit/ddddf2a178e4e9bf3d52efb07cd05820ce109f43)
const server = net.createServer(socket => {
// 'connection' listener
console.log('PHP process connected');
socket.on('end', () => {
console.log('PHP process disconnected');
});
server.close();
resolve({ reader: socket, writer: socket });
});
// Listen on random port
server.listen(0, '127.0.0.1', () => {
const args = [];
const spawnServer = (...args: string[]): ChildProcess => {
if (additionalCLIFlags.length > 0) {
args.unshift(...additionalCLIFlags);
}
// Start the language server and connect to the client listening on <addr> (e.g. 127.0.0.1:<port>)
args.unshift('--language-server-tcp-connect=127.0.0.1:' + server.address().port);
// Aside: Max setting is 4095M
if (memoryLimit && memoryLimit.length > 0) {
args.unshift('--memory-limit', memoryLimit);
Expand Down Expand Up @@ -279,7 +263,30 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
});
}
return childProcess;
});
};
// NOTE: Phan isn't going to work on win32, unless we use linux subsystem (Haven't tried) or docker... and if docker is used, you'd have to use stdin.

// Use a TCP socket on Windows because of problems with blocking STDIO
// stdio locks up for large responses
// (based on https://github.com/felixfbecker/vscode-php-intellisense/commit/ddddf2a178e4e9bf3d52efb07cd05820ce109f43)
if (!connectToServerWithStdio || process.platform === 'win32') {
const server = net.createServer(socket => {
// 'connection' listener
console.log('PHP process connected');
socket.on('end', () => {
console.log('PHP process disconnected');
});
server.close();
resolve({ reader: socket, writer: socket });
});
server.listen(0, '127.0.0.1', () => {
// Start the language server and make the language server connect to the client listening on <addr> (e.g. 127.0.0.1:<port>)
spawnServer('--language-server-tcp-connect=127.0.0.1:' + server.address().port);
});
} else {
// Use STDIO on Linux / Mac if the user set the override `connectToServerWithStdio: true` in their config
resolve(spawnServer('--language-server-on-stdin'));
}
});

// Options to control the language client
Expand Down

0 comments on commit 156c40d

Please sign in to comment.