From a3ab81af8b5351ab7e0ad4302bd7c1bfbdfcfaeb Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Tue, 29 Aug 2023 16:50:39 -0400 Subject: [PATCH 1/4] Remove ember-template-imports in favor of content-tag --- .../-private/environment/preprocess.ts | 47 +++++++++++++++---- .../package.json | 7 +-- yarn.lock | 7 ++- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/packages/environment-ember-template-imports/-private/environment/preprocess.ts b/packages/environment-ember-template-imports/-private/environment/preprocess.ts index 4ebb76d53..1754b333b 100644 --- a/packages/environment-ember-template-imports/-private/environment/preprocess.ts +++ b/packages/environment-ember-template-imports/-private/environment/preprocess.ts @@ -1,14 +1,42 @@ import { GlintExtensionPreprocess } from '@glint/core/config-types'; -import { parseTemplates } from 'ember-template-imports'; import { GLOBAL_TAG, PreprocessData, TemplateLocation } from './common'; - +/** + * We don't need to actually generate the code that would be emitted for + * a real app to build, we can use placeholders, so we have less offsets + * to worry about (precompile, setComponentTemplate, their imports, etc) + */ const TEMPLATE_START = `[${GLOBAL_TAG}\``; const TEMPLATE_END = '`]'; +// NOTE: This import is a lie -- We are not real ESM, and this is compiled to CJS. +// ESM usage would be different here, and this is the CJS version of content-tag. +import { Preprocessor } from 'content-tag'; +const p = new Preprocessor(); + +interface Parsed { + type: 'expression' | 'class-member'; + tagName: 'template'; + contents: string; + range: { + start: number; + end: number; + }; + contentRange: { + start: number; + end: number; + }; + startRange: { + end: number; + start: number; + }; + endRange: { + start: number; + end: number; + }; +} + export const preprocess: GlintExtensionPreprocess = (source, path) => { - let templates = parseTemplates(source, path, { templateTag: 'template' }).filter( - (match) => match.type === 'template-tag' - ); + let templates = p.parse(source, path) as Parsed[]; let templateLocations: Array = []; let segments: Array = []; @@ -16,11 +44,10 @@ export const preprocess: GlintExtensionPreprocess = (source, pat let delta = 0; for (let template of templates) { - let { start, end } = template; - let startTagLength = template.start[0].length; - let endTagLength = template.end[0].length; - let startTagOffset = start.index ?? -1; - let endTagOffset = end.index ?? -1; + let startTagLength = template.startRange.end - template.startRange.start; + let endTagLength = template.endRange.end - template.endRange.start; + let startTagOffset = template.startRange.start; + let endTagOffset = template.endRange.start; if (startTagOffset === -1 || endTagOffset === -1) continue; diff --git a/packages/environment-ember-template-imports/package.json b/packages/environment-ember-template-imports/package.json index 288a48a4e..7c2079c95 100644 --- a/packages/environment-ember-template-imports/package.json +++ b/packages/environment-ember-template-imports/package.json @@ -26,14 +26,16 @@ "-private/**/*.{js,d.ts}", "globals/index.d.ts" ], + "dependencies": { + "content-tag": "^1.1.0" + }, "peerDependencies": { "@glint/environment-ember-loose": "^1.2.1", "@glint/template": "^1.2.1", "@types/ember__component": "^4.0.10", "@types/ember__helper": "^4.0.1", "@types/ember__modifier": "^4.0.3", - "@types/ember__routing": "^4.0.12", - "ember-template-imports": "^3.0.0" + "@types/ember__routing": "^4.0.12" }, "peerDependenciesMeta": { "@types/ember__component": { @@ -55,7 +57,6 @@ "@types/ember__helper": "^4.0.1", "@types/ember__modifier": "^4.0.3", "@types/ember__routing": "^4.0.12", - "ember-template-imports": "^3.0.0", "vitest": "^0.22.0" }, "publishConfig": { diff --git a/yarn.lock b/yarn.lock index 4912405a4..c4d97bf5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5151,6 +5151,11 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" +content-tag@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/content-tag/-/content-tag-1.1.0.tgz#fcef4bdcf1850f9b67bf0b6f7aee217c6d7ea9fa" + integrity sha512-bktivDORs9M890KwVKrIONYvHhwshfgF4b1G/TFPrjH12Ag2GDiSdxVHqIzMxWZ297VgIRPSImURlpcOzJP/LQ== + content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -6461,7 +6466,7 @@ ember-template-imports@^1.1.1: ember-cli-version-checker "^5.1.2" validate-peer-dependencies "^1.1.0" -ember-template-imports@^3.0.0, ember-template-imports@^3.1.1: +ember-template-imports@^3.1.1: version "3.4.0" resolved "https://registry.yarnpkg.com/ember-template-imports/-/ember-template-imports-3.4.0.tgz#c40757e2d41e289ce08c0fe80671000bf216e0ef" integrity sha512-3Cwcj3NXA129g3ZhmrQ/nYOxksFonTmB/qxyaSNTHrLBSoc93UZys47hBz13DlcfoeSCCrNt2Qpq1j890I04PQ== From 57b30f924496f5f6f6e52a46b6171309a2cb0a8c Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 13 Oct 2023 22:30:58 -0400 Subject: [PATCH 2/4] Forward rust-parser errors to the language server --- .../src/transform/template/rewrite-module.ts | 35 +++++++++++++++++-- .../-private/environment/preprocess.ts | 2 -- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/core/src/transform/template/rewrite-module.ts b/packages/core/src/transform/template/rewrite-module.ts index 7ae8a9662..6cec07b27 100644 --- a/packages/core/src/transform/template/rewrite-module.ts +++ b/packages/core/src/transform/template/rewrite-module.ts @@ -71,7 +71,11 @@ function calculateCorrelatedSpans( let errors: Array = []; let partialSpans: Array = []; - let { ast, emitMetadata } = parseScript(ts, script, environment); + let { ast, emitMetadata, error } = parseScript(ts, script, environment); + + if (error) { + errors.push({ message: error, location: { start: 0, end: 0 }, source: script }); + } ts.transform(ast, [ (context) => @@ -106,6 +110,7 @@ function calculateCorrelatedSpans( type ParseResult = { ast: ts.SourceFile; emitMetadata: WeakMap; + error?: string; }; function parseScript(ts: TSLib, script: SourceFile, environment: GlintEnvironment): ParseResult { @@ -116,7 +121,31 @@ function parseScript(ts: TSLib, script: SourceFile, environment: GlintEnvironmen void emitMetadata.set(node, Object.assign(emitMetadata.get(node) ?? {}, data)); let { preprocess, transform } = environment.getConfigForExtension(extension) ?? {}; - let preprocessed = preprocess?.(contents, filename) ?? { contents }; + let original: { + contents: string; + data?: { + // SAFETY: type exists elsewhere (the environments) + templateLocations: any[]; + }; + } = { contents, data: { templateLocations: [] } }; + let preprocessed = original; + let error: string | undefined; + + try { + preprocessed = preprocess?.(contents, filename) ?? original; + } catch (e) { + if (typeof e === 'object' && e !== null) { + // Parse Errors from the rust parser + if ('source_code' in e) { + // @ts-expect-error object / property narrowing isn't available until TS 5.1 + error = e.source_code; + } + } else { + console.log(e); + error = `${e}`; + } + } + let ast = ts.createSourceFile( filename, preprocessed.contents, @@ -133,7 +162,7 @@ function parseScript(ts: TSLib, script: SourceFile, environment: GlintEnvironmen ast = transformed[0]; } - return { ast, emitMetadata }; + return { ast, emitMetadata, error }; } /** diff --git a/packages/environment-ember-template-imports/-private/environment/preprocess.ts b/packages/environment-ember-template-imports/-private/environment/preprocess.ts index 1754b333b..56c9d5540 100644 --- a/packages/environment-ember-template-imports/-private/environment/preprocess.ts +++ b/packages/environment-ember-template-imports/-private/environment/preprocess.ts @@ -8,8 +8,6 @@ import { GLOBAL_TAG, PreprocessData, TemplateLocation } from './common'; const TEMPLATE_START = `[${GLOBAL_TAG}\``; const TEMPLATE_END = '`]'; -// NOTE: This import is a lie -- We are not real ESM, and this is compiled to CJS. -// ESM usage would be different here, and this is the CJS version of content-tag. import { Preprocessor } from 'content-tag'; const p = new Preprocessor(); From c2eab669764e9b1453e8393624babc02c0bfcd47 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:41:28 -0400 Subject: [PATCH 3/4] When we have a parsing error, focus on that instead of overwhelming the user with every error possible --- packages/core/src/common/transform-manager.ts | 13 ++++ .../language-server/glint-language-server.ts | 3 + .../src/transform/template/rewrite-module.ts | 72 +++++++++++++++++-- .../ts-template-imports-app/src/index.gts | 7 +- 4 files changed, 84 insertions(+), 11 deletions(-) diff --git a/packages/core/src/common/transform-manager.ts b/packages/core/src/common/transform-manager.ts index fd849f0e3..1444974e2 100644 --- a/packages/core/src/common/transform-manager.ts +++ b/packages/core/src/common/transform-manager.ts @@ -63,7 +63,11 @@ export default class TransformManager { ): ReadonlyArray { let unusedExpectErrors = new Set(this.getExpectErrorDirectives(fileName)); let allDiagnostics = []; + for (let diagnostic of diagnostics) { + if (diagnostic.messageText === `Cannot find name 'template'`) { + continue; + } let { rewrittenDiagnostic, appliedDirective } = this.rewriteDiagnostic(diagnostic); if (rewrittenDiagnostic) { allDiagnostics.push(rewrittenDiagnostic); @@ -85,6 +89,15 @@ export default class TransformManager { ); } + // When we have syntax errors we get _too many errors_ + // if we have an issue with +2=; +export const Y = ; \ No newline at end of file From f6ba22a0c8c29a405639c1678a0e636d786d6b4c Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:42:00 -0400 Subject: [PATCH 4/4] Revert changes to test-package file --- test-packages/ts-template-imports-app/src/index.gts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test-packages/ts-template-imports-app/src/index.gts b/test-packages/ts-template-imports-app/src/index.gts index 000673eb4..f479dee5f 100644 --- a/test-packages/ts-template-imports-app/src/index.gts +++ b/test-packages/ts-template-imports-app/src/index.gts @@ -1,2 +1,5 @@ -2=; -export const Y = ; \ No newline at end of file +import Greeting from './Greeting'; + +export default