Skip to content

Add glint-language-server to @glint/core #44

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

Merged
merged 18 commits into from
Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion packages/config/__tests__/include-exclude.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ describe('include/exclude configuration', () => {
expect(config.includesFile(`${root}/deeply/nested/file.ts`)).toBe(true);
});

test('includes all .hbs files within the root', () => {
expect(config.includesFile(`${root}/file.hbs`)).toBe(true);
expect(config.includesFile(`${root}/deeply/nested/file.hbs`)).toBe(true);
});

test('excludes files outside the root', () => {
expect(config.includesFile(`${root}/../other.ts`)).toBe(false);
});

test('excludes non-.ts files', () => {
test('excludes non-.ts/.hbs files', () => {
expect(config.includesFile(`${root}/other.txt`)).toBe(false);
});

Expand Down
7 changes: 6 additions & 1 deletion packages/config/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ export class GlintConfig {
this.rootDir = normalizePath(rootDir);
this.environment = GlintEnvironment.load(config.environment, { rootDir });

let include = Array.isArray(config.include) ? config.include : [config.include ?? '**/*.ts'];
let include = Array.isArray(config.include)
? config.include
: config.include
? [config.include]
: ['**/*.ts', '**/*.hbs'];

let exclude = Array.isArray(config.exclude)
? config.exclude
: [config.exclude ?? '**/node_modules/**'];
Expand Down
9 changes: 5 additions & 4 deletions packages/core/__tests__/cli/check.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { stripIndent } from 'common-tags';
import stripAnsi from 'strip-ansi';
import Project from '../utils/project';

describe('single-pass typechecking', () => {
describe('CLI: single-pass typechecking', () => {
let project!: Project;
beforeEach(async () => {
jest.setTimeout(20_000);
project = await Project.create();
});

Expand Down Expand Up @@ -64,13 +65,13 @@ describe('single-pass typechecking', () => {
expect(checkResult.exitCode).toBe(1);
expect(checkResult.stdout).toEqual('');
expect(stripAnsi(checkResult.stderr)).toMatchInlineSnapshot(`
"index.ts:10:28 - error TS0: [glint] Parse error on line 2:
"index.ts:11:24 - error TS0: Parse error on line 2:
...e to app v{{@version}. The current t
-----------------------^
Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SEXPR', 'ID', 'OPEN_BLOCK_PARAMS', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', 'SEP', got 'INVALID'

10 public static template = hbs\`
~~~
11 Welcome to app v{{@version}.
~~~~~~~
"
`);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/core/__tests__/cli/declaration.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { stripIndent } from 'common-tags';
import Project from '../utils/project';

describe('emitting declarations', () => {
describe('CLI: emitting declarations', () => {
let project!: Project;
beforeEach(async () => {
project = await Project.create();
Expand Down
8 changes: 4 additions & 4 deletions packages/core/__tests__/cli/watch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import stripAnsi from 'strip-ansi';
import os from 'os';
import Project from '../utils/project';

describe('watched typechecking', () => {
describe('CLI: watched typechecking', () => {
let project!: Project;
beforeEach(async () => {
jest.setTimeout(20_000);
Expand Down Expand Up @@ -75,13 +75,13 @@ describe('watched typechecking', () => {

expect(output).toMatch('Found 1 error.');
expect(error.replace(/\r/g, '')).toMatchInlineSnapshot(`
"index.ts:10:28 - error TS0: [glint] Parse error on line 2:
"index.ts:11:24 - error TS0: Parse error on line 2:
...e to app v{{@version}. The current t
-----------------------^
Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SEXPR', 'ID', 'OPEN_BLOCK_PARAMS', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', 'SEP', got 'INVALID'

10 public static template = hbs\`
~~~"
11 Welcome to app v{{@version}.
~~~~~~~"
`);
});

Expand Down
3 changes: 3 additions & 0 deletions packages/core/bin/glint-language-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node
/* eslint-disable */
require('../lib/language-server');
6 changes: 5 additions & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"bin"
],
"bin": {
"glint": "bin/glint.js"
"glint": "bin/glint.js",
"glint-language-server": "bin/glint-language-server.js"
},
"scripts": {
"lint": "eslint . --max-warnings 0 && prettier --check src",
Expand All @@ -23,6 +24,9 @@
"@glint/config": "^0.2.1",
"@glint/transform": "^0.2.1",
"resolve": "^1.17.0",
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.1",
"vscode-uri": "^3.0.2",
"yargs": "^15.3.1"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { loadConfig } from '@glint/config';
import { performWatch } from './perform-watch';
import { performCheck } from './perform-check';
import { determineOptionsToExtend } from './options';
import { loadTypeScript } from './load-typescript';
import { loadTypeScript } from '../common/load-typescript';

const { argv } = yargs
.scriptName('glint')
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/cli/perform-check.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type ts from 'typescript';
import TransformManager from './transform-manager';
import TransformManager from '../common/transform-manager';
import { GlintConfig } from '@glint/config';

export function performCheck(
Expand Down Expand Up @@ -46,7 +46,7 @@ function createCompilerHost(
transformManager: TransformManager
): ts.CompilerHost {
let host = ts.createCompilerHost(options);
host.readFile = transformManager.readFile;
host.readFile = transformManager.readTransformedFile;
return host;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/cli/perform-watch.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import TransformManager from './transform-manager';
import TransformManager from '../common/transform-manager';
import { GlintConfig } from '@glint/config';

export function performWatch(
Expand Down Expand Up @@ -27,8 +27,8 @@ function sysForWatchCompilerHost(
): typeof ts.sys {
return {
...ts.sys,
watchFile: transformManager.watchFile,
readFile: transformManager.readFile,
watchFile: transformManager.watchTransformedFile,
readFile: transformManager.readTransformedFile,
};
}

Expand All @@ -47,7 +47,7 @@ function patchProgram(program: Program, transformManager: TransformManager): voi
let { getSyntacticDiagnostics } = program;
program.getSyntacticDiagnostics = function (sourceFile, cancelationToken) {
let diagnostics = getSyntacticDiagnostics.call(program, sourceFile, cancelationToken);
let transformDiagnostics = transformManager.getTransformDiagnostics(sourceFile);
let transformDiagnostics = transformManager.getTransformDiagnostics(sourceFile?.fileName);
return [...diagnostics, ...transformDiagnostics];
};
}
113 changes: 0 additions & 113 deletions packages/core/src/cli/transform-manager.ts

This file was deleted.

113 changes: 113 additions & 0 deletions packages/core/src/common/document-cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { GlintConfig } from '@glint/config';

export type Document = {
version: number;
contents: string;
stale: boolean;
};

/**
* A read-through cache for workspace document contents.
*
* This cache is aware (via the glint configuration it's instantiated with)
* of the relationship between certain `.ts` and `.hbs` files, and will
* treat a change to one member of such pairs as affecting the version
* of both.
*/
export default class DocumentCache {
private readonly documents = new Map<string, Document>();

public constructor(private ts: typeof import('typescript'), private glintConfig: GlintConfig) {}

public documentExists(path: string): boolean {
return this.documents.has(path) || this.ts.sys.fileExists(path);
}

public getCompanionDocumentPath(path: string): string | undefined {
let { environment } = this.glintConfig;
let candidates = isTemplate(path)
? environment.getPossibleScriptPaths(path)
: environment.getPossibleTemplatePaths(path);

for (let candidate of candidates) {
if (this.documentExists(candidate)) {
return candidate;
}
}
}

public getDocumentContents(path: string, encoding?: string): string {
if (!this.documentExists(path)) return '';

let document = this.getDocument(path);
if (document.stale) {
document.contents = this.ts.sys.readFile(path, encoding) ?? '';
document.stale = false;
}

return document.contents;
}

public getCompoundDocumentVersion(path: string): string {
let template = isTemplate(path) ? this.getDocument(path) : this.findCompanionDocument(path);
let script = isTemplate(path) ? this.findCompanionDocument(path) : this.getDocument(path);

return `${script?.version}:${template?.version}`;
}

public getDocumentVersion(path: string): string {
return this.getDocument(path).version.toString();
}

public updateDocument(path: string, contents: string): void {
let document = this.getDocument(path);

document.stale = false;
document.contents = contents;
document.version++;

this.incrementCompanionVersion(path);
}

public markDocumentStale(path: string): void {
let document = this.getDocument(path);

document.stale = true;
document.version++;

this.incrementCompanionVersion(path);
}

public removeDocument(path: string): void {
this.documents.delete(path);
}

private incrementCompanionVersion(path: string): void {
let companion = this.findCompanionDocument(path);
if (companion) {
companion.version++;
}
}

private findCompanionDocument(path: string): Document | undefined {
let companionPath = this.getCompanionDocumentPath(path);
return companionPath ? this.getDocument(companionPath) : undefined;
}

private getDocument(path: string): Document {
let document = this.documents.get(path);
if (!document) {
document = { version: 0, contents: '', stale: true };
this.documents.set(path, document);
}
return document;
}
}

export function isTemplate(path: string): boolean {
return path.endsWith('.hbs');
}

export function isScript(path: string): boolean {
return path.endsWith('.ts');
}
Loading