Skip to content

Commit c66a2d1

Browse files
author
Keen Yee Liau
committed
feat: add Session class and refactor server.js
This PR moves most of the code in server.js to a standalone module named Session, which provides an encapsulation of LSP connection. Since server.js is a script and not a module, it should not contain too much code.
1 parent f25d1b4 commit c66a2d1

File tree

14 files changed

+606
-500
lines changed

14 files changed

+606
-500
lines changed

client/src/extension.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,14 @@ export function activate(context: vscode.ExtensionContext) {
1717
// Log file does not yet exist on disk. It is up to the server to create the
1818
// file.
1919
const logFile = path.join(context.logPath, 'nglangsvc.log');
20-
const pluginProbeLocation = context.asAbsolutePath('server');
20+
const ngProbeLocations = [
21+
process.cwd(), // workspace version
22+
context.asAbsolutePath('server'), // bundled version
23+
];
24+
const tsProbeLocations = [
25+
process.cwd(), // workspace version
26+
context.extensionPath, // bundled version
27+
];
2128

2229
// If the extension is launched in debug mode then the debug server options are used
2330
// Otherwise the run options are used
@@ -29,8 +36,10 @@ export function activate(context: vscode.ExtensionContext) {
2936
'--logFile',
3037
logFile,
3138
// TODO: Might want to turn off logging completely.
32-
'--pluginProbeLocation',
33-
pluginProbeLocation,
39+
'--ngProbeLocations',
40+
ngProbeLocations.join(','),
41+
'--tsProbeLocations',
42+
tsProbeLocations.join(','),
3443
],
3544
options: {
3645
env: {
@@ -47,8 +56,10 @@ export function activate(context: vscode.ExtensionContext) {
4756
logFile,
4857
'--logVerbosity',
4958
'verbose',
50-
'--pluginProbeLocation',
51-
pluginProbeLocation,
59+
'--ngProbeLocations',
60+
ngProbeLocations.join(','),
61+
'--tsProbeLocations',
62+
tsProbeLocations.join(','),
5263
],
5364
options: {
5465
env: {

integration/lsp/smoke_spec.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ class ResponseEmitter extends EventEmitter {}
88

99
describe('Angular Language Service', () => {
1010
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; /* 10 seconds */
11+
const PACKAGE_ROOT = resolve(__dirname, '../../..');
1112
const PROJECT_PATH = resolve(__dirname, '../../project');
1213
const SERVER_PATH = resolve(__dirname, '../../../server/out/server.js');
1314
const responseEmitter = new ResponseEmitter();
@@ -31,12 +32,21 @@ describe('Angular Language Service', () => {
3132
}
3233

3334
beforeEach(() => {
34-
server = fork(SERVER_PATH, ['--node-ipc'], {
35-
cwd: PROJECT_PATH,
36-
env: {
37-
TSC_NONPOLLING_WATCHER: 'true',
38-
},
39-
});
35+
server = fork(
36+
SERVER_PATH,
37+
[
38+
'--node-ipc',
39+
'--tsProbeLocations',
40+
PACKAGE_ROOT,
41+
'--ngProbeLocations',
42+
PROJECT_PATH,
43+
],
44+
{
45+
cwd: PROJECT_PATH,
46+
env: {
47+
TSC_NONPOLLING_WATCHER: 'true',
48+
},
49+
});
4050
server.on('error', fail);
4151
server.on('close', (code, signal) => {
4252
console.log(`Server 'close' event received`, code, signal);

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
"jasmine": "^3.4.0",
5353
"rollup": "^1.23.1",
5454
"rollup-plugin-commonjs": "^10.1.0",
55-
"rollup-plugin-node-resolve": "^5.2.0",
5655
"tslint": "^5.19.0",
5756
"tslint-eslint-rules": "^5.4.0",
5857
"vsce": "^1.66.0",

rollup.config.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as fs from 'fs';
22
import commonjs from 'rollup-plugin-commonjs';
3-
import nodeResolve from 'rollup-plugin-node-resolve';
43

54
module.exports = [
65
{
@@ -16,7 +15,6 @@ module.exports = [
1615
'vscode-languageclient',
1716
],
1817
plugins: [
19-
nodeResolve(),
2018
commonjs(),
2119
],
2220
},
@@ -35,8 +33,12 @@ module.exports = [
3533
'vscode-uri',
3634
],
3735
plugins: [
38-
nodeResolve(),
39-
commonjs(),
36+
commonjs({
37+
ignore: [
38+
// leave require statements unconverted.
39+
'conditional-runtime-dependency',
40+
],
41+
}),
4042
],
4143
},
4244
];

server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"node": "*"
1010
},
1111
"dependencies": {
12-
"@angular/language-service": "^9.0.0-next.7",
12+
"@angular/language-service": "^9.0.0-next.9",
1313
"vscode-languageserver": "~5.2.1",
1414
"vscode-uri": "^2.0.3"
1515
}

server/src/banner.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,17 @@ function define(modules, cb) {
77
const arg = process.argv[index + 1];
88
return arg.split(',');
99
}
10-
const TSSERVER = 'typescript/lib/tsserverlibrary';
11-
let tsserverPath;
12-
try {
13-
tsserverPath = require.resolve(TSSERVER, {
14-
paths: parseStringArray('--typeScriptProbeLocations'),
15-
});
10+
function resolve(packageName, paths) {
11+
try {
12+
return require.resolve(packageName, {paths});
13+
}
14+
catch {}
1615
}
17-
catch {}
16+
const TSSERVER = 'typescript/lib/tsserverlibrary';
1817
const resolvedModules = modules.map(m => {
19-
if (m === 'typescript') {
20-
throw new Error(`'typescript' should never be used. Use '${TSSERVER}' instead.`)
21-
}
22-
if (tsserverPath && m === TSSERVER) {
23-
return require(tsserverPath);
18+
if (m === TSSERVER || m === 'typescript') {
19+
const tsProbeLocations = parseStringArray('--tsProbeLocations');
20+
m = resolve(TSSERVER, tsProbeLocations) || TSSERVER;
2421
}
2522
return require(m);
2623
});

server/src/logger.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,18 @@ import * as ts from 'typescript/lib/tsserverlibrary';
2929
// TLDR: To log to development console, always use connection.console.log().
3030
// Never use console.log(), console.info(), etc directly.
3131

32+
export interface LoggerOptions {
33+
logFile?: string;
34+
logVerbosity?: string;
35+
}
36+
3237
/**
3338
* Create a logger instance to write to file.
3439
* @param options Logging options.
3540
*/
36-
export function createLogger(options: Map<string, string>) {
37-
const logFile = options.get('logFile') || path.join(fs.mkdtempSync('ng_'), 'ngserver.log');
38-
const logVerbosity = options.get('logVerbosity') || 'normal';
41+
export function createLogger(options: LoggerOptions): Logger {
3942
let logLevel: ts.server.LogLevel;
40-
switch (logVerbosity) {
43+
switch (options.logVerbosity) {
4144
case 'terse':
4245
logLevel = ts.server.LogLevel.terse;
4346
break;
@@ -48,11 +51,15 @@ export function createLogger(options: Map<string, string>) {
4851
logLevel = ts.server.LogLevel.verbose;
4952
break;
5053
case 'normal':
54+
logLevel = ts.server.LogLevel.normal;
55+
break;
5156
default:
5257
logLevel = ts.server.LogLevel.terse;
5358
break;
5459
}
55-
return new Logger(logFile, false /* traceToConsole */, logLevel);
60+
// If logFile is not provided then just trace to console.
61+
const traceToConsole = !options.logFile;
62+
return new Logger(traceToConsole, logLevel, options.logFile);
5663
}
5764

5865
// TODO: Code below is from TypeScript's repository. Maybe create our own
@@ -74,8 +81,10 @@ export class Logger implements ts.server.Logger {
7481
private firstInGroup = true;
7582

7683
constructor(
77-
private readonly logFilename: string, private readonly traceToConsole: boolean,
78-
private readonly level: ts.server.LogLevel) {
84+
private readonly traceToConsole: boolean,
85+
private readonly level: ts.server.LogLevel,
86+
private readonly logFilename?: string,
87+
) {
7988
if (logFilename) {
8089
try {
8190
const dir = path.dirname(logFilename);

0 commit comments

Comments
 (0)