Skip to content
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
4 changes: 1 addition & 3 deletions packages/core/src/transform/diagnostics/augmentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ export function augmentDiagnostics<T extends Diagnostic>(
const start = diagnostic.start;
const end = start + diagnostic.length;

// TODO: de-hardwire "disregard.gts" and consider the case of two-file components where
// the hardcoded source file name might be the hbs file.
const rangeWithMappingAndSource = transformedModule.getTransformedRange(
'disregard.gts',
transformedModule.originalFileName,
start,
end,
);
Expand Down
17 changes: 14 additions & 3 deletions packages/core/src/transform/template/rewrite-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export type RewriteInput = { script: SourceFile; template?: SourceFile };
//
// 1. It doesn't break Organize Imports command
// 2. It doesn't introduce any keywords/variables that'll show up in auto-complete suggestions
const EXTENSION_FIXING_HEADER_HACK = `
const EXTENSION_FIXING_HEADER_HACK_GTS = `
// @ts-expect-error
({} as typeof import('./__glint-hacky-nonexistent.gts'));

Expand All @@ -42,6 +42,15 @@ const EXTENSION_FIXING_HEADER_HACK = `

`;

const EXTENSION_FIXING_HEADER_HACK_GJS = `
// @ts-expect-error
(/** @type {typeof import("./__glint-hacky-nonexistent.gts")} */ ({}))

// @ts-expect-error
(/** @type {typeof import("./__glint-hacky-nonexistent.gjs")} */ ({}))

`;

/**
* Given the script and/or template that together comprise a component module,
* returns a `TransformedModule` representing the combined result, with the
Expand Down Expand Up @@ -70,7 +79,7 @@ export function rewriteModule(
let sparseSpans = completeCorrelatedSpans(partialSpans);
let { contents, correlatedSpans } = calculateTransformedSource(script, sparseSpans);

return new TransformedModule(contents, errors, directives, correlatedSpans);
return new TransformedModule(contents, errors, directives, correlatedSpans, script.filename);
}

/**
Expand All @@ -94,7 +103,9 @@ function calculateCorrelatedSpans(
originalStart: 0,
originalLength: 0,
insertionPoint: 0,
transformedSource: EXTENSION_FIXING_HEADER_HACK,
transformedSource: environment.isUntypedScript(script.filename)
? EXTENSION_FIXING_HEADER_HACK_GJS
: EXTENSION_FIXING_HEADER_HACK_GTS,
},
];

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/transform/template/transformed-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default class TransformedModule {
public readonly errors: ReadonlyArray<TransformError>,
public readonly directives: ReadonlyArray<Directive>,
public readonly correlatedSpans: Array<CorrelatedSpan>,
public readonly originalFileName: string,
) {}

public toDebugString(): string {
Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/volar/gts-virtual-code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,11 @@ export class VirtualGtsCode implements VirtualCode {
};

const contents = snapshot.getText(0, length);

let script = { filename: 'disregard.gts', contents };
const isJavascript =
this.languageId === 'glimmer-js' || this.languageId === 'javascript.glimmer';
const embeddedLanguageId = isJavascript ? 'javascript' : 'typescript';
const filename = isJavascript ? 'root.gjs' : 'root.gts';
let script = { filename, contents };
let template = undefined;

const transformedModule = rewriteModule(
Expand All @@ -149,7 +152,7 @@ export class VirtualGtsCode implements VirtualCode {
{
embeddedCodes: [],
id: 'ts',
languageId: 'typescript',
languageId: embeddedLanguageId,
mappings,
snapshot: new ScriptSnapshot(transformedModule.transformedContents),
directives: transformedModule.directives,
Expand Down Expand Up @@ -213,7 +216,7 @@ export class VirtualGtsCode implements VirtualCode {
{
embeddedCodes: [],
id: 'ts',
languageId: 'typescript',
languageId: embeddedLanguageId,
mappings: [
{
// Hacked hardwired values for now.
Expand Down
2 changes: 1 addition & 1 deletion packages/tsserver-plugin/src/typescript-server-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function getCompletionsAtPosition<T>(
const transformedModule: TransformedModule = root?.transformedModule;
const completions = getCompletionsAtPosition(fileName, position, options, formattingSettings);
const transformedRange = transformedModule?.getTransformedRange(
'disregard.gts',
transformedModule.originalFileName,
position,
position,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Component from '@glimmer/component';

export default class Greeting extends Component {
message = 'Hello';

<template>
{{this.message}}, {{@target}}!
</template>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import Component from '@glimmer/component';
import Colocated from './colocated-folder';
import Greeting from './GreetingUntyped';

export default class Other extends Component {
message = 'Hello';

<template>
<Greeting @target="World" />
<Colocated @target="World" />
</template>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"target": "es2019",
"module": "es2015",
"moduleResolution": "bundler",
"skipLibCheck": true
"skipLibCheck": true,
"checkJs": true
},
"glint": {
"environment": ["ember-loose", "ember-template-imports"]
Expand Down
4 changes: 2 additions & 2 deletions packages/vscode/__tests__/helpers/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}

export async function waitUntil(callback: () => unknown): Promise<void> {
export async function waitUntil(callback: () => unknown, message?: string): Promise<void> {
let start = Date.now();
while (Date.now() - start < 15_000) {
if (await callback()) {
Expand All @@ -12,5 +12,5 @@ export async function waitUntil(callback: () => unknown): Promise<void> {
await sleep(500);
}

throw new Error(`waitUntil condition never came true`);
throw new Error(`waitUntil condition never came true (${message})`);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('Smoke test: Loose Mode + GTS with TS Plugin Mode', () => {
let scriptEditor = await window.showTextDocument(scriptURI, { viewColumn: ViewColumn.One });

// Wait for a diagnostic to appear in the template
await waitUntil(() => languages.getDiagnostics(scriptURI).length);
await waitUntil(() => languages.getDiagnostics(scriptURI).length, 'diagnostic to appear');

expect(languages.getDiagnostics(scriptURI)).toMatchObject([
{
Expand All @@ -51,7 +51,10 @@ describe('Smoke test: Loose Mode + GTS with TS Plugin Mode', () => {
});

// Wait for the diagnostic to disappear
await waitUntil(() => languages.getDiagnostics(scriptURI).length == 0);
await waitUntil(
() => languages.getDiagnostics(scriptURI).length == 0,
'diagnostic to disappear',
);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { TextDocument } from 'vscode-languageserver-textdocument';
describe('Language Server: Document Symbols (language server)', () => {
afterEach(teardownSharedTestWorkspaceAfterEach);

test('component invocation', async () => {
test('typed gts file', async () => {
const document = await prepareDocument(
'ts-template-imports-app/src/empty-fixture.gts',
'glimmer-ts',
Expand Down Expand Up @@ -108,6 +108,104 @@ describe('Language Server: Document Symbols (language server)', () => {
]
`);
});

test('untyped gjs file', async () => {
const document = await prepareDocument(
'ts-template-imports-app/src/empty-fixture-untyped.gjs',
'glimmer-js',
stripIndent`
import Component from '@glimmer/component';
import Greeting from './Greeting.gts';

export default class Application extends Component {
<template>
<Greeting @message="hello" />
</template>
}
`,
);

const symbols = await performDocumentSymbolsRequest(document);

expect(symbols).toMatchInlineSnapshot(`
[
{
"children": [
{
"kind": 8,
"name": "Greeting",
"range": {
"end": {
"character": 33,
"line": 5,
},
"start": {
"character": 4,
"line": 5,
},
},
"selectionRange": {
"end": {
"character": 33,
"line": 5,
},
"start": {
"character": 4,
"line": 5,
},
},
},
{
"kind": 2,
"name": "template",
"range": {
"end": {
"character": 13,
"line": 6,
},
"start": {
"character": 2,
"line": 4,
},
},
"selectionRange": {
"end": {
"character": 13,
"line": 6,
},
"start": {
"character": 2,
"line": 4,
},
},
},
],
"kind": 5,
"name": "Application",
"range": {
"end": {
"character": 1,
"line": 7,
},
"start": {
"character": 0,
"line": 3,
},
},
"selectionRange": {
"end": {
"character": 32,
"line": 3,
},
"start": {
"character": 21,
"line": 3,
},
},
},
]
`);
});
});

async function performDocumentSymbolsRequest(document: TextDocument): Promise<any> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,10 +421,10 @@ describe('Transform: rewriteModule', () => {
expect(transformedModule?.transformedContents).toMatchInlineSnapshot(`
"
// @ts-expect-error
({} as typeof import('./__glint-hacky-nonexistent.gts'));
(/** @type {typeof import("./__glint-hacky-nonexistent.gts")} */ ({}))

// @ts-expect-error
({} as typeof import('./__glint-hacky-nonexistent.gjs'));
(/** @type {typeof import("./__glint-hacky-nonexistent.gjs")} */ ({}))

import templateOnly from '@glimmer/component/template-only';

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// This file is intentionally empty.
// It exists as a hack to get around some issues when testing our TS Plugin
// within tsserver harness where, even though many of our tests are only
// updating tsserver's in-memory content for a file, tsserver still needs
// the file to exist in the file system in order for things like References
// and other language features to work properly.
Loading