Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: nx lsp #1316

Merged
merged 27 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
64b8bb4
feat: nx lsp
Cammisuli Jul 28, 2022
c635416
rename server to utils
Cammisuli Jul 28, 2022
89d74dd
add lsp deps
Cammisuli Jul 28, 2022
2ecfe27
add json-langaugeservice
Cammisuli Jul 29, 2022
edcd5d3
fix debug for lsp server
Cammisuli Aug 2, 2022
7bd50ea
move json-schema lib
Cammisuli Aug 2, 2022
2479121
refactor packages to remove dependencies on vscode
Cammisuli Aug 3, 2022
087b243
load schemas
Cammisuli Aug 3, 2022
c5c09de
fix merge mistakes
Cammisuli Aug 3, 2022
d21e699
fix circular dep and add json document cache from vscode
Cammisuli Aug 3, 2022
352e767
remove $schema fields to get full oncomplete with the json language s…
Cammisuli Aug 3, 2022
bbc79b3
add lsp-client lib
Cammisuli Aug 3, 2022
27a248a
add package.json + package command
Cammisuli Aug 4, 2022
38061b0
correct dist path
Cammisuli Aug 4, 2022
a997ba5
add bin
Cammisuli Aug 4, 2022
ac5a7a1
add ls as implicit dep
Cammisuli Aug 4, 2022
8a3c574
fix watch
Cammisuli Aug 4, 2022
8c7748e
fix ui build
Cammisuli Aug 4, 2022
997f219
add devkit as dep
Cammisuli Aug 5, 2022
bd2c291
clean up generated project schema, add hover provider
Cammisuli Aug 5, 2022
dfcd7ff
move schema test
Cammisuli Aug 5, 2022
cf234b4
make sure that the ls can be ran within the extension on prod builds
Cammisuli Aug 8, 2022
e5b271e
fix tests
Cammisuli Aug 9, 2022
a7b9440
clean up
Cammisuli Aug 9, 2022
463c810
add max old space to all nx commands
Cammisuli Aug 9, 2022
f1c8799
more memory for node
Cammisuli Aug 9, 2022
a76c752
skip builds on ci
Cammisuli Aug 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/nx-run/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ runs:
- name: Test
run: yarn nx run-many --all --parallel --target=test --max-parallel=3
shell: bash
- name: Build
run: yarn nx run-many --all --parallel --target=build --max-parallel=3
shell: bash
- name: Stopping nx-cloud ci agents
run: npx nx-cloud stop-all-agents
shell: bash
24 changes: 22 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
"<node_internals>/**",
"/Applications/Visual Studio Code.app/**"
],
"type": "pwa-extensionHost"
"type": "extensionHost"
},
{
"name": "Run Extension In Dev Mode",
"type": "pwa-extensionHost",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
Expand All @@ -37,9 +37,29 @@
"outFiles": [
"${workspaceFolder}/dist/apps/vscode",
"${workspaceFolder}/dist/apps/vscode/assets/public",
"!${workspaceFolder}/dist/apps/vscode/lsp",
"${workspaceFolder}/node_modules"
],
"preLaunchTask": "npm: watch"
},
{
"type": "node",
"request": "attach",
"name": "Attach to LSP Server",
"port": 6009,
"restart": true,
"sourceMaps": true,
"skipFiles": [
"<node_internals>/**",
"/Applications/Visual Studio Code.app/**"
]
// "outFiles": ["${workspaceFolder}/dist/vscode/lsp/**/*.js"]
}
],
"compounds": [
{
"name": "Launch Client + Server",
"configurations": ["Launch Extension", "Attach to LSP Server"]
}
]
}
18 changes: 18 additions & 0 deletions apps/nxls/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
16 changes: 16 additions & 0 deletions apps/nxls/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* eslint-disable */
export default {
displayName: 'nxls',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
},
},
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/apps/nxls',
};
18 changes: 18 additions & 0 deletions apps/nxls/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "nxls",
"version": "0.0.1",
"main": "main.js",
"bin": "bin/nxls",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/nrwl/nx-console.git"
},
"author": {
"name": "Narwhal Technologies Inc",
"email": "hello@nrwl.io"
},
"dependencies": {
"@nrwl/devkit": "14.4.1"
}
}
64 changes: 64 additions & 0 deletions apps/nxls/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"sourceRoot": "apps/nxls/src",
"projectType": "application",
"targets": {
"watch": {
"executor": "@nrwl/node:webpack",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/apps/vscode/nxls",
"main": "apps/nxls/src/main.ts",
"tsConfig": "apps/nxls/tsconfig.app.json",
"assets": ["apps/nxls/src/assets"],
"watch": true
}
},
"package": {
"executor": "@nrwl/node:webpack",
"options": {
"main": "apps/nxls/src/main.ts",
"tsConfig": "apps/nxls/tsconfig.app.json",
"outputPath": "dist/packages/nxls",
"assets": ["apps/nxls/src/bin"],
"generatePackageJson": true,
"externalDependencies": "all",
"optimization": true,
"extractLicenses": true
}
},
"build": {
"executor": "nx:run-commands",
"outputs": ["dist/apps/vscode/nxls"],
"options": {
"commands": [
"export NODE_OPTIONS=--max-old-space-size=4096 && yarn rollup -c ./apps/nxls/rollup.config.ts"
]
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/nxls/**/*.ts"]
}
},
"test": {
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/apps/nxls"],
"options": {
"jestConfig": "apps/nxls/jest.config.ts",
"passWithNoTests": true
}
},
"semantic-release": {
"executor": "@theunderscorer/nx-semantic-release:semantic-release",
"options": {
"buildTarget": "nxls:package",
"outputPath": "dist/packages/nxls",
"packageJsonDir": "apps/nxls",
"ci": false
}
}
},
"tags": []
}
31 changes: 31 additions & 0 deletions apps/nxls/rollup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import ts from '@rollup/plugin-typescript';
import cjs from '@rollup/plugin-commonjs';
import nodeResolve from '@rollup/plugin-node-resolve';
import json from '@rollup/plugin-json';
import replace from '@rollup/plugin-replace';
import { terser } from 'rollup-plugin-terser';
import { defineConfig } from 'rollup';

export default defineConfig({
input: './apps/nxls/src/main.ts',
output: {
file: './dist/apps/vscode/nxls/main.js',
format: 'cjs',
plugins: [terser()],
},
plugins: [
replace({
values: {
"'string_decoder/'": "'string_decoder'",
},
delimiters: ['', ''],
preventAssignment: true,
}),
nodeResolve({ preferBuiltins: true, exportConditions: ['node'] }),
json(),
cjs(),
ts({
tsconfig: './apps/nxls/tsconfig.app.json',
}),
],
});
Empty file added apps/nxls/src/assets/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions apps/nxls/src/bin/nxls
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node

require('../main.js');
3 changes: 3 additions & 0 deletions apps/nxls/src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const environment = {
production: true,
};
3 changes: 3 additions & 0 deletions apps/nxls/src/environments/environment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const environment = {
production: false,
};
7 changes: 7 additions & 0 deletions apps/nxls/src/global-polyfills.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable */

// needed for rollup builds because one of the dependent libraries have a non_webpack_require (essentially the nx package resolve util)
declare var __non_webpack_require__: typeof require;
if (!globalThis.__non_webpack_require__) {
globalThis.__non_webpack_require__ = require;
}
118 changes: 118 additions & 0 deletions apps/nxls/src/languageModelCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// https://github.com/microsoft/vscode/blob/89c30e1b86f941db095d9f52b128287e5039e004/extensions/json-language-features/server/src/languageModelCache.ts

import { JSONDocument } from 'vscode-json-languageservice';
import { TextDocument } from 'vscode-languageserver-textdocument';

export interface LanguageModelCache<T> {
get(document: TextDocument): { jsonAst: T; document: TextDocument };
onDocumentRemoved(document: TextDocument): void;
dispose(): void;
}

export function getLanguageModelCache(
maxEntries: number,
cleanupIntervalTimeInSec: number,
parse: (document: TextDocument) => JSONDocument
): LanguageModelCache<JSONDocument> {
let languageModels: {
[uri: string]: {
version: number;
languageId: string;
cTime: number;
languageModel: JSONDocument;
document: TextDocument;
};
} = {};
let nModels = 0;

let cleanupInterval: NodeJS.Timer | undefined = undefined;
if (cleanupIntervalTimeInSec > 0) {
cleanupInterval = setInterval(() => {
const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
const uris = Object.keys(languageModels);
for (const uri of uris) {
const languageModelInfo = languageModels[uri];
if (languageModelInfo.cTime < cutoffTime) {
delete languageModels[uri];
nModels--;
}
}
}, cleanupIntervalTimeInSec * 1000);
}

return {
get(document: TextDocument): {
jsonAst: JSONDocument;
document: TextDocument;
} {
const version = document.version;
const languageId = document.languageId;
const languageModelInfo = languageModels[document.uri];
if (
languageModelInfo &&
languageModelInfo.version === version &&
languageModelInfo.languageId === languageId
) {
languageModelInfo.cTime = Date.now();
return {
jsonAst: languageModelInfo.languageModel,
document: languageModelInfo.document,
};
}
const newDocument = TextDocument.create(
document.uri,
document.languageId,
document.version,
document.getText().replace(/"\$schema":\s".+",/, '')
);
const languageModel = parse(newDocument);

languageModels[document.uri] = {
languageModel,
version,
languageId,
document: newDocument,
cTime: Date.now(),
};
if (!languageModelInfo) {
nModels++;
}

if (nModels === maxEntries) {
let oldestTime = Number.MAX_VALUE;
let oldestUri = null;
for (const uri in languageModels) {
const languageModelInfo = languageModels[uri];
if (languageModelInfo.cTime < oldestTime) {
oldestUri = uri;
oldestTime = languageModelInfo.cTime;
}
}
if (oldestUri) {
delete languageModels[oldestUri];
nModels--;
}
}
return { jsonAst: languageModel, document: newDocument };
},
onDocumentRemoved(document: TextDocument) {
const uri = document.uri;
if (languageModels[uri]) {
delete languageModels[uri];
nModels--;
}
},
dispose() {
if (typeof cleanupInterval !== 'undefined') {
clearInterval(cleanupInterval);
cleanupInterval = undefined;
languageModels = {};
nModels = 0;
}
},
};
}
Loading