test: delete integration test for language service plugin (#41740)

This commit deletes the integration test for `@angular/language-service`
as a plugin to the standard tsserver.

In version 12, Ivy LS will replace legacy View Engine LS as the default,
and Ivy LS plugin cannot be loaded via `tsconfig.json` due to the need to
run ngcc. This makes the test irrelevant.

PR Close #41740
This commit is contained in:
Keen Yee Liau 2021-04-21 00:06:10 -07:00 committed by Jessica Janiuk
parent 98fc4f4b2f
commit a0a373be8d
26 changed files with 0 additions and 1052 deletions

View File

@ -29,7 +29,6 @@ integration/hello_world__systemjs_umd/node_modules
integration/i18n/node_modules integration/i18n/node_modules
integration/injectable-def/node_modules integration/injectable-def/node_modules
integration/ivy-i18n/node_modules integration/ivy-i18n/node_modules
integration/language_service_plugin/node_modules
integration/ng_elements/node_modules integration/ng_elements/node_modules
integration/ng_elements_schematics/node_modules integration/ng_elements_schematics/node_modules
integration/ng_update/node_modules integration/ng_update/node_modules
@ -56,7 +55,6 @@ integration/hello_world__systemjs_umd/.yarn_local_cache
integration/i18n/.yarn_local_cache integration/i18n/.yarn_local_cache
integration/injectable-def/.yarn_local_cache integration/injectable-def/.yarn_local_cache
integration/ivy-i18n/.yarn_local_cache integration/ivy-i18n/.yarn_local_cache
integration/language_service_plugin/.yarn_local_cache
integration/ng_elements/.yarn_local_cache integration/ng_elements/.yarn_local_cache
integration/ng_elements_schematics/.yarn_local_cache integration/ng_elements_schematics/.yarn_local_cache
integration/ng_update/.yarn_local_cache integration/ng_update/.yarn_local_cache
@ -83,7 +81,6 @@ integration/hello_world__systemjs_umd/NPM_PACKAGE_MANIFEST.json
integration/i18n/NPM_PACKAGE_MANIFEST.json integration/i18n/NPM_PACKAGE_MANIFEST.json
integration/injectable-def/NPM_PACKAGE_MANIFEST.json integration/injectable-def/NPM_PACKAGE_MANIFEST.json
integration/ivy-i18n/NPM_PACKAGE_MANIFEST.json integration/ivy-i18n/NPM_PACKAGE_MANIFEST.json
integration/language_service_plugin/NPM_PACKAGE_MANIFEST.json
integration/ng_elements/NPM_PACKAGE_MANIFEST.json integration/ng_elements/NPM_PACKAGE_MANIFEST.json
integration/ng_elements_schematics/NPM_PACKAGE_MANIFEST.json integration/ng_elements_schematics/NPM_PACKAGE_MANIFEST.json
integration/ng_update/NPM_PACKAGE_MANIFEST.json integration/ng_update/NPM_PACKAGE_MANIFEST.json

View File

@ -79,7 +79,6 @@ INTEGRATION_TESTS = {
"injectable-def": {"tags": ["no-ivy-aot"]}, "injectable-def": {"tags": ["no-ivy-aot"]},
"ivy-i18n": {"tags": ["ivy-only"]}, "ivy-i18n": {"tags": ["ivy-only"]},
"trusted-types": {"tags": ["ivy-only"]}, "trusted-types": {"tags": ["ivy-only"]},
"language_service_plugin": {},
"ng_elements": {"tags": ["no-ivy-aot"]}, "ng_elements": {"tags": ["no-ivy-aot"]},
"ng_elements_schematics": {"tags": ["ivy-only"]}, "ng_elements_schematics": {"tags": ["ivy-only"]},
"ng_update": {}, "ng_update": {},

View File

@ -1,3 +0,0 @@
*.js
tsserver.log
ti-*.log

View File

@ -1,32 +0,0 @@
# Angular Language Service Test
This directory is an integration test for `@angular/language-service` to ensure
that the language service works correctly as a `tsserver` plugin.
To use the tests:
- Use `yarn install` to install all dependencies in this directory and in the Angular repo root
directory.
- Build an Angular distribution with `yarn build-dist`. This needs to be done after changes to
Angular, but not after changes to integration tests. This is an expensive build.
- In this directory, run the integration tests with `yarn test`.
## Update golden files
If the expected output needs to be updated, run `yarn golden my-golden.json`, replacing
`my-golden.json` with the golden file to be updated. Do not qualify the file with a directory path.
See [generate.ts](./generate.ts) for more information.
## Adding a new fixture
Currently there is no automated way to produce a new fixture. The way the
current fixtures were created was to hack a version of tsserver.js to write the
commands from `VSCode` to a file while performing the operation to be tested.
I also hand modified the input to remove superfluous request.
Once a new fixture is created:
1) Add the fixture name to `goldens/`
2) Run `yarn golden my-golden.json`, replacing `my-golden.json` with the new fixture name, to
produce the expected output files.
3) Hand validate that the expected output is reasonable.

View File

@ -1,22 +0,0 @@
/**
* @fileOverview
* This file serves as the entry point for generating goldens file for the
* language service integration test. It expects each golden file that needs
* to be generated to be passed in as command line arguments.
* For example, to generate golden file for the 'configure' request, run
* `yarn golden configure.json`.
* To generate multiple golden files, run
* `yarn golden configure.json completionInfo.json`.
*
* This is different from just running `yarn jasmine test.js` because this
* allows passing in arbitrary arguments.
*/
import Jasmine = require('jasmine');
function main() {
const jasmine = new Jasmine({});
jasmine.execute(['test.js']);
}
main()

View File

@ -1,8 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "compilerOptionsForInferredProjects",
"request_seq": 1,
"success": true,
"body": true
}

View File

@ -1,293 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "completionInfo",
"request_seq": 5,
"success": true,
"performanceData": {
"updateGraphDurationMs": 34.82808400003705
},
"body": {
"isGlobalCompletion": false,
"isMemberCompletion": false,
"isNewIdentifierLocation": false,
"entries": [
{
"name": "anchor",
"kind": "method",
"sortText": "anchor",
"insertText": "anchor()"
},
{
"name": "big",
"kind": "method",
"sortText": "big",
"insertText": "big()"
},
{
"name": "blink",
"kind": "method",
"sortText": "blink",
"insertText": "blink()"
},
{
"name": "bold",
"kind": "method",
"sortText": "bold",
"insertText": "bold()"
},
{
"name": "charAt",
"kind": "method",
"sortText": "charAt",
"insertText": "charAt()"
},
{
"name": "charCodeAt",
"kind": "method",
"sortText": "charCodeAt",
"insertText": "charCodeAt()"
},
{
"name": "codePointAt",
"kind": "method",
"sortText": "codePointAt",
"insertText": "codePointAt()"
},
{
"name": "concat",
"kind": "method",
"sortText": "concat",
"insertText": "concat()"
},
{
"name": "endsWith",
"kind": "method",
"sortText": "endsWith",
"insertText": "endsWith()"
},
{
"name": "fixed",
"kind": "method",
"sortText": "fixed",
"insertText": "fixed()"
},
{
"name": "fontcolor",
"kind": "method",
"sortText": "fontcolor",
"insertText": "fontcolor()"
},
{
"name": "fontsize",
"kind": "method",
"sortText": "fontsize",
"insertText": "fontsize()"
},
{
"name": "includes",
"kind": "method",
"sortText": "includes",
"insertText": "includes()"
},
{
"name": "indexOf",
"kind": "method",
"sortText": "indexOf",
"insertText": "indexOf()"
},
{
"name": "italics",
"kind": "method",
"sortText": "italics",
"insertText": "italics()"
},
{
"name": "lastIndexOf",
"kind": "method",
"sortText": "lastIndexOf",
"insertText": "lastIndexOf()"
},
{
"name": "length",
"kind": "property",
"sortText": "length",
"insertText": "length"
},
{
"name": "link",
"kind": "method",
"sortText": "link",
"insertText": "link()"
},
{
"name": "localeCompare",
"kind": "method",
"sortText": "localeCompare",
"insertText": "localeCompare()"
},
{
"name": "match",
"kind": "method",
"sortText": "match",
"insertText": "match()"
},
{
"name": "normalize",
"kind": "method",
"sortText": "normalize",
"insertText": "normalize()"
},
{
"name": "padEnd",
"kind": "method",
"sortText": "padEnd",
"insertText": "padEnd()"
},
{
"name": "padStart",
"kind": "method",
"sortText": "padStart",
"insertText": "padStart()"
},
{
"name": "repeat",
"kind": "method",
"sortText": "repeat",
"insertText": "repeat()"
},
{
"name": "replace",
"kind": "method",
"sortText": "replace",
"insertText": "replace()"
},
{
"name": "search",
"kind": "method",
"sortText": "search",
"insertText": "search()"
},
{
"name": "slice",
"kind": "method",
"sortText": "slice",
"insertText": "slice()"
},
{
"name": "small",
"kind": "method",
"sortText": "small",
"insertText": "small()"
},
{
"name": "split",
"kind": "method",
"sortText": "split",
"insertText": "split()"
},
{
"name": "startsWith",
"kind": "method",
"sortText": "startsWith",
"insertText": "startsWith()"
},
{
"name": "strike",
"kind": "method",
"sortText": "strike",
"insertText": "strike()"
},
{
"name": "sub",
"kind": "method",
"sortText": "sub",
"insertText": "sub()"
},
{
"name": "substr",
"kind": "method",
"sortText": "substr",
"insertText": "substr()"
},
{
"name": "substring",
"kind": "method",
"sortText": "substring",
"insertText": "substring()"
},
{
"name": "sup",
"kind": "method",
"sortText": "sup",
"insertText": "sup()"
},
{
"name": "toLocaleLowerCase",
"kind": "method",
"sortText": "toLocaleLowerCase",
"insertText": "toLocaleLowerCase()"
},
{
"name": "toLocaleUpperCase",
"kind": "method",
"sortText": "toLocaleUpperCase",
"insertText": "toLocaleUpperCase()"
},
{
"name": "toLowerCase",
"kind": "method",
"sortText": "toLowerCase",
"insertText": "toLowerCase()"
},
{
"name": "toString",
"kind": "method",
"sortText": "toString",
"insertText": "toString()"
},
{
"name": "toUpperCase",
"kind": "method",
"sortText": "toUpperCase",
"insertText": "toUpperCase()"
},
{
"name": "trim",
"kind": "method",
"sortText": "trim",
"insertText": "trim()"
},
{
"name": "trimEnd",
"kind": "method",
"sortText": "trimEnd",
"insertText": "trimEnd()"
},
{
"name": "trimLeft",
"kind": "method",
"sortText": "trimLeft",
"insertText": "trimLeft()"
},
{
"name": "trimRight",
"kind": "method",
"sortText": "trimRight",
"insertText": "trimRight()"
},
{
"name": "trimStart",
"kind": "method",
"sortText": "trimStart",
"insertText": "trimStart()"
},
{
"name": "valueOf",
"kind": "method",
"sortText": "valueOf",
"insertText": "valueOf()"
}
]
}
}

View File

@ -1,7 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "configure",
"request_seq": 0,
"success": true
}

View File

@ -1,20 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "definition",
"request_seq": 2,
"success": true,
"body": [
{
"file": "${PWD}/project/app/app.component.ts",
"start": {
"line": 7,
"offset": 30
},
"end": {
"line": 7,
"offset": 47
}
}
]
}

View File

@ -1,32 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "definitionAndBoundSpan",
"request_seq": 2,
"success": true,
"body": {
"definitions": [
{
"file": "${PWD}/project/app/app.component.ts",
"start": {
"line": 7,
"offset": 30
},
"end": {
"line": 7,
"offset": 47
}
}
],
"textSpan": {
"start": {
"line": 5,
"offset": 26
},
"end": {
"line": 5,
"offset": 30
}
}
}
}

View File

@ -1,22 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "quickinfo",
"request_seq": 2,
"success": true,
"body": {
"kind": "property",
"kindModifiers": "",
"start": {
"line": 5,
"offset": 26
},
"end": {
"line": 5,
"offset": 30
},
"displayString": "(property) AppComponent.name: string",
"documentation": "",
"tags": []
}
}

View File

@ -1,32 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "definitionAndBoundSpan",
"request_seq": 3,
"success": true,
"body": {
"definitions": [
{
"file": "${PWD}/project/app/style.css",
"start": {
"line": 1,
"offset": 1
},
"end": {
"line": 1,
"offset": 1
}
}
],
"textSpan": {
"start": {
"line": 6,
"offset": 16
},
"end": {
"line": 6,
"offset": 27
}
}
}
}

View File

@ -1,32 +0,0 @@
{
"seq": 0,
"type": "response",
"command": "definitionAndBoundSpan",
"request_seq": 2,
"success": true,
"body": {
"definitions": [
{
"file": "${PWD}/project/app/widget.component.html",
"start": {
"line": 1,
"offset": 1
},
"end": {
"line": 1,
"offset": 1
}
}
],
"textSpan": {
"start": {
"line": 5,
"offset": 17
},
"end": {
"line": 5,
"offset": 40
}
}
}
}

View File

@ -1,35 +0,0 @@
import { writeFileSync, readFileSync } from 'fs';
const goldens: string[] = process.argv.slice(2);
export const goldenMatcher: jasmine.CustomMatcherFactories = {
toMatchGolden(util: jasmine.MatchersUtil): jasmine.CustomMatcher {
return {
compare(actual: {body?: {}}, golden: string): jasmine.CustomMatcherResult {
if (goldens.includes(golden)) {
console.error(`Writing golden file ${golden}`);
writeFileSync(`./goldens/${golden}`, JSON.stringify(actual, null, 2));
return { pass : true };
}
const content = readFileSync(`./goldens/${golden}`, 'utf-8');
const expected = JSON.parse(content.replace("${PWD}", process.env.PWD!));
const hasBody = Object.hasOwnProperty.call(expected, 'body');
const pass = hasBody ? util.equals(actual.body, expected.body) : util.equals(actual, expected);
return {
pass,
message: `Expected ${JSON.stringify(actual, null, 2)} to match golden ` +
`${JSON.stringify(expected, null, 2)}.\n` +
`To generate new golden file, run "yarn golden ${golden}".`,
};
}
};
},
};
declare global {
namespace jasmine {
interface Matchers<T> {
toMatchGolden(golden: string): void
}
}
}

View File

@ -1,21 +0,0 @@
{
"name": "language_service_plugin",
"version": "0.0.0",
"license": "MIT",
"description": "Angular Language Service plugin integration test",
"dependencies": {
"@angular/core": "file:../../dist/packages-dist/core",
"@angular/language-service": "file:../../dist/packages-dist/language-service",
"@types/jasmine": "file:../../node_modules/@types/jasmine",
"@types/node": "file:../../node_modules/@types/node",
"jasmine": "file:../../node_modules/jasmine",
"typescript": "file:../../node_modules/typescript"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"build-dist": "node ../../scripts/build/build-packages-dist.js && yarn install --check-files",
"cleanup": "rm -rf ti-*.log tsserver.log",
"golden": "yarn build && node generate.js",
"test": "yarn cleanup && yarn build && jasmine test.js"
}
}

View File

@ -1,7 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `<h1>Hello {{name}}</h1><my-widget></my-widget>`,
})
export class AppComponent { name = 'Angular'; }

View File

@ -1,12 +0,0 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { WidgetComponent } from './widget.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent, WidgetComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -1,5 +0,0 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

View File

@ -1,4 +0,0 @@
body,
html {
width: 100%;
}

View File

@ -1 +0,0 @@
<h1>This is a {{name}} widget!</h1>

View File

@ -1,8 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'my-widget',
templateUrl: './widget.component.html',
styleUrls: ['./style.css'],
})
export class WidgetComponent { name = 'Angular'; }

View File

@ -1,16 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"plugins": [
{"name": "@angular/language-service"}
]
}
}

View File

@ -1,203 +0,0 @@
import {ChildProcess, fork} from 'child_process';
import {join} from 'path';
import {goldenMatcher} from './matcher';
import {Client} from './tsclient';
describe('Angular Language Service', () => {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; /* 10 seconds */
const PWD = process.env.PWD!;
const SERVER_PATH = './node_modules/typescript/lib/tsserver.js';
let server: ChildProcess;
let client: Client;
beforeEach(() => {
jasmine.addMatchers(goldenMatcher);
server = fork(
SERVER_PATH,
[
'--logVerbosity',
'verbose',
'--logFile',
join(PWD, 'tsserver.log'),
],
{
stdio: ['pipe', 'pipe', 'inherit', 'ipc'],
});
client = new Client(server);
client.listen();
});
afterEach(async () => {
client.sendRequest('exit', {});
// Give server process some time to flush all messages
await new Promise((resolve) => setTimeout(resolve, 1000));
});
it('should be launched as tsserver plugin', async () => {
let response = await client.sendRequest('configure', {
hostInfo: 'vscode',
});
expect(response).toMatchGolden('configure.json');
response = await client.sendRequest('compilerOptionsForInferredProjects', {
'options': {
module: 'CommonJS',
target: 'ES6',
allowSyntheticDefaultImports: true,
allowNonTsExtensions: true,
allowJs: true,
jsx: 'Preserve'
}
});
expect(response).toMatchGolden('compilerOptionsForInferredProjects.json');
// Server does not send response to open request
// https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts#L1055
client.sendRequest('open', {
file: `${PWD}/project/app/app.module.ts`,
});
// Server does not send response to geterr request
// https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts#L1770
client.sendRequest('geterr', {delay: 0, files: [`${PWD}/project/app/app.module.ts`]});
});
it('should perform completions', async () => {
await client.sendRequest('configure', {
hostInfo: 'vscode',
});
await client.sendRequest('compilerOptionsForInferredProjects', {
'options': {
module: 'CommonJS',
target: 'ES6',
allowSyntheticDefaultImports: true,
allowNonTsExtensions: true,
allowJs: true,
jsx: 'Preserve'
}
});
client.sendRequest('open', {
file: `${PWD}/project/app/app.component.ts`,
});
client.sendRequest('geterr', {delay: 0, files: [`${PWD}/project/app/app.component.ts`]});
client.sendRequest('change', {
file: `${PWD}/project/app/app.component.ts`,
line: 5,
offset: 30,
endLine: 5,
endOffset: 30,
insertString: '.',
});
const response = await client.sendRequest('completionInfo', {
file: `${PWD}/project/app/app.component.ts`,
line: 5,
offset: 31,
});
expect(response).toMatchGolden('completionInfo.json');
});
it('should perform quickinfo', async () => {
client.sendRequest('open', {
file: `${PWD}/project/app/app.component.ts`,
});
const resp1 = await client.sendRequest('reload', {
file: `${PWD}/project/app/app.component.ts`,
tmpFile: `${PWD}/project/app/app.component.ts`,
}) as any;
expect(resp1.command).toBe('reload');
expect(resp1.success).toBe(true);
const resp2 = await client.sendRequest('quickinfo', {
file: `${PWD}/project/app/app.component.ts`,
line: 5,
offset: 28,
});
expect(resp2).toMatchGolden('quickinfo.json');
});
it('should perform definition', async () => {
client.sendRequest('open', {
file: `${PWD}/project/app/app.component.ts`,
});
const resp1 = await client.sendRequest('reload', {
file: `${PWD}/project/app/app.component.ts`,
tmpFile: `${PWD}/project/app/app.component.ts`,
}) as any;
expect(resp1.command).toBe('reload');
expect(resp1.success).toBe(true);
const resp2 = await client.sendRequest('definition', {
file: `${PWD}/project/app/app.component.ts`,
line: 5,
offset: 28,
});
expect(resp2).toMatchGolden('definition.json');
});
it('should perform definitionAndBoundSpan', async () => {
client.sendRequest('open', {
file: `${PWD}/project/app/app.component.ts`,
});
const resp1 = await client.sendRequest('reload', {
file: `${PWD}/project/app/app.component.ts`,
tmpFile: `${PWD}/project/app/app.component.ts`,
}) as any;
expect(resp1.command).toBe('reload');
expect(resp1.success).toBe(true);
const resp2 = await client.sendRequest('definitionAndBoundSpan', {
file: `${PWD}/project/app/app.component.ts`,
line: 5,
offset: 28,
});
expect(resp2).toMatchGolden('definitionAndBoundSpan.json');
});
it('should perform definitionAndBoundSpan for template URLs', async () => {
client.sendRequest('open', {
file: `${PWD}/project/app/widget.component.ts`,
});
const resp1 = await client.sendRequest('reload', {
file: `${PWD}/project/app/widget.component.ts`,
tmpFile: `${PWD}/project/app/widget.component.ts`,
}) as any;
expect(resp1.command).toBe('reload');
expect(resp1.success).toBe(true);
const resp2 = await client.sendRequest('definitionAndBoundSpan', {
file: `${PWD}/project/app/widget.component.ts`,
line: 5,
offset: 19,
});
expect(resp2).toMatchGolden('templateUrlDefinition.json');
});
it('should perform definitionAndBoundSpan for style URLs', async () => {
client.sendRequest('open', {
file: `${PWD}/project/app/widget.component.ts`,
});
client.sendRequest('open', {
file: `${PWD}/project/app/style.css`,
});
const resp1 = await client.sendRequest('reload', {
file: `${PWD}/project/app/widget.component.ts`,
tmpFile: `${PWD}/project/app/widget.component.ts`,
}) as any;
expect(resp1.command).toBe('reload');
expect(resp1.success).toBe(true);
const resp2 = await client.sendRequest('definitionAndBoundSpan', {
file: `${PWD}/project/app/widget.component.ts`,
line: 6,
offset: 18,
});
expect(resp2).toMatchGolden('styleUrlsDefinition.json');
});
});

View File

@ -1,75 +0,0 @@
import { ChildProcess } from "child_process";
import { EventEmitter } from "events";
/**
* Provides a client for tsserver. Tsserver does not use standard JSON-RPC
* protocol thus the need for this custom client.
*/
export class Client {
private data: Buffer|undefined;
private id = 0;
private responseEmitter = new EventEmitter();
constructor(private readonly server: ChildProcess) {}
listen() {
this.server.stdout!.on('data', (data: Buffer) => {
this.data = this.data ? Buffer.concat([this.data, data]) : data;
// tsserver could batch multiple responses together so we have to go
// through the entire buffer to keep looking for messages.
const CONTENT_LENGTH = 'Content-Length: '
do {
const index = this.data.indexOf(CONTENT_LENGTH);
if (index < 0) {
return;
}
let start = index + CONTENT_LENGTH.length;
let end = this.data.indexOf('\r\n', start);
if (end < start) {
return;
}
const contentLengthStr = this.data.slice(start, end).toString();
const contentLength = Number(contentLengthStr);
if (isNaN(contentLength) || contentLength < 0) {
return;
}
start = end + 4;
end = start + contentLength;
if (end > this.data.length) {
return;
}
const content = this.data.slice(start, end).toString();
this.data = this.data.slice(end);
try {
const payload = JSON.parse(content);
if (payload.type === "response") {
const seq = `${payload.request_seq}`;
this.responseEmitter.emit(seq, payload);
}
}
catch (error) {
this.responseEmitter.emit('error', error);
}
} while (this.data.length > 0)
});
}
async send(type: string, command: string, params: {}) {
const seq = this.id++;
const request = {
seq,
type,
command,
arguments: params
};
this.server.stdin!.write(JSON.stringify(request) + '\r\n');
return new Promise((resolve, reject) => {
this.responseEmitter.once(`${seq}`, resolve);
this.responseEmitter.once('error', reject);
});
}
async sendRequest(command: string, params: {}) {
return this.send('request', command, params);
}
}

View File

@ -1,60 +0,0 @@
{
"compilerOptions": {
/* Basic Options */
"target": "es2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
"typeRoots": ["node_modules/@types"], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
},
"include": ["*.ts"]
}

View File

@ -1,98 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@angular/core@file:../../dist/packages-dist/core":
version "9.0.0-rc.1"
"@angular/language-service@file:../../dist/packages-dist/language-service":
version "9.0.0-rc.1"
"@types/node@file:../../node_modules/@types/node":
version "12.11.1"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
glob@^7.0.6:
version "7.1.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
jasmine-core@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.3.0.tgz#dea1cdc634bc93c7e0d4ad27185df30fa971b10e"
integrity sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA==
"jasmine@file:../../node_modules/jasmine":
version "3.3.1"
dependencies:
glob "^7.0.6"
jasmine-core "~3.3.0"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
dependencies:
brace-expansion "^1.1.7"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
dependencies:
wrappy "1"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
"typescript@file:../../node_modules/typescript":
version "3.6.4"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=