Skip to content

Commit

Permalink
Refactored syntax validation tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
wycats committed Feb 23, 2025
1 parent c13ab39 commit 0683762
Show file tree
Hide file tree
Showing 29 changed files with 1,271 additions and 705 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pre {
line-height: 1.2;
font-family: ui-monospace, 'Cascadia Mono', 'Segoe UI Mono', 'Noto Sans Mono', monospace;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export async function bootQunit(
export async function setupQunit() {
const qunitLib: QUnit = await import('qunit');
await import('qunit/qunit/qunit.css');
await import('./harness/tweaks.css');

const testing = Testing.withConfig(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ class DynamicModifiersResolutionModeTest extends RenderTest {

@test
'Cannot invoke a modifier definition based on this fallback lookup in resolution mode'() {
this.registerComponent('TemplateOnly', 'Bar', '<div {{x.foo}}></div>');
this.registerComponent('TemplateOnly', 'Bar', `<div\n {{x.foo}}></div>`);

this.assert.throws(
() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { CURRIED_COMPONENT, CURRIED_HELPER } from '@glimmer/constants';
import { ASTv2, generateSyntaxError, src } from '@glimmer/syntax';

import type { NormalizationState } from '../context';
import type { ContentKeywordMatch } from './impl';

import { Err, Ok, Result } from '../../../shared/result';
import * as mir from '../../2-encoding/mir';
import { visitCurlyArgs, visitExpr, visitPositional } from '../visitors/expressions';
Expand Down Expand Up @@ -51,19 +48,11 @@ export const APPEND_KEYWORDS = keywords('Append')
}
},

translate(
{ node, state }: { node: ContentKeywordMatch; state: NormalizationState },
{
target,
positional,
}: {
target: src.SourceSlice;
positional: ASTv2.PositionalArguments;
}
): Result<mir.Content> {
translate({ node, keyword, state }, { target, positional }): Result<mir.Content> {
return visitPositional(positional, state).mapOk(
(positional) =>
new mir.Yield({
keyword,
loc: node.loc,
target,
to: state.scope.allocateBlock(target.chars),
Expand All @@ -89,15 +78,15 @@ export const APPEND_KEYWORDS = keywords('Append')
}
},

translate({ node, state: { scope } }): Result<mir.Content> {
return Ok(new mir.Debugger({ loc: node.loc, scope }));
translate({ node, keyword, state: { scope } }): Result<mir.Content> {
return Ok(new mir.Debugger({ keyword, loc: node.loc, scope }));
},
})
.kw('component', {
assert: assertCurryKeyword(CURRIED_COMPONENT),

translate(
{ node, state },
{ node, keyword, state },
{ definition, args }
): Result<mir.InvokeComponentKeyword | mir.InvokeResolvedComponentKeyword> {
let definitionResult = visitExpr(definition, state);
Expand All @@ -116,6 +105,7 @@ export const APPEND_KEYWORDS = keywords('Append')

return Ok(
new mir.InvokeResolvedComponentKeyword({
keyword,
loc: node.loc,
definition: definition.value,
args,
Expand All @@ -125,6 +115,7 @@ export const APPEND_KEYWORDS = keywords('Append')

return Ok(
new mir.InvokeComponentKeyword({
keyword,
loc: node.loc,
definition,
args,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { Err, Ok, Result } from '../../../shared/result';
import * as mir from '../../2-encoding/mir';
import {
visitCurlyArgs,
visitCurlyNamedArguments,
visitExpr,
visitNamedArguments,
visitPositional,
} from '../visitors/expressions';
import { visitNamedBlock, visitNamedBlocks } from '../visitors/statements';
Expand All @@ -17,7 +17,7 @@ import { assertCurryKeyword } from './utils/curry';
export const BLOCK_KEYWORDS = keywords('Block')
.kw('in-element', {
assert(node): Result<{
insertBefore: ASTv2.ExpressionValueNode | null;
insertBefore: ASTv2.CurlyArgument | null;
destination: ASTv2.ExpressionValueNode;
}> {
let { args } = node;
Expand All @@ -28,7 +28,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Err(generateSyntaxError(`Cannot pass \`guid\` to \`{{#in-element}}\``, guid.loc));
}

let insertBefore = args.get('insertBefore');
let insertBefore = args.getNode('insertBefore');
let destination = args.nth(0);

if (destination === null) {
Expand All @@ -45,7 +45,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Ok({ insertBefore, destination });
},

translate({ node, state }, { insertBefore, destination }): Result<mir.InElement> {
translate({ node, keyword, state }, { insertBefore, destination }): Result<mir.InElement> {
let named = node.blocks.get('default');
let body = visitNamedBlock(named, state);
let destinationResult = visitExpr(destination, state);
Expand All @@ -55,13 +55,13 @@ export const BLOCK_KEYWORDS = keywords('Block')
([body, destination]): Result<{
body: mir.NamedBlock;
destination: mir.ExpressionValueNode;
insertBefore: mir.ExpressionValueNode | mir.Missing;
insertBefore: mir.CustomNamedArgument<mir.ExpressionValueNode> | mir.Missing;
}> => {
if (insertBefore) {
return visitExpr(insertBefore, state).mapOk((insertBefore) => ({
return visitExpr(insertBefore.value, state).mapOk((insertBeforeValue) => ({
body,
destination,
insertBefore,
insertBefore: mir.CustomNamedArgument.from(insertBefore, insertBeforeValue),
}));
} else {
return Ok({
Expand All @@ -77,6 +77,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
.mapOk(
({ body, destination, insertBefore }) =>
new mir.InElement({
keyword,
loc: node.loc,
block: body,
insertBefore,
Expand Down Expand Up @@ -126,7 +127,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Ok({ condition });
},

translate({ node, state }, { condition }): Result<mir.IfContent> {
translate({ node, keyword, state }, { condition }): Result<mir.IfContent> {
let block = node.blocks.get('default');
let inverse = node.blocks.get('else');

Expand All @@ -137,6 +138,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Result.all(conditionResult, blockResult, inverseResult).mapOk(
([condition, block, inverse]) =>
new mir.IfContent({
keyword,
loc: node.loc,
condition,
block,
Expand Down Expand Up @@ -185,7 +187,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Ok({ condition });
},

translate({ node, state }, { condition }): Result<mir.IfContent> {
translate({ node, keyword, state }, { condition }): Result<mir.IfContent> {
let block = node.blocks.get('default');
let inverse = node.blocks.get('else');

Expand All @@ -196,6 +198,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Result.all(conditionResult, blockResult, inverseResult).mapOk(
([condition, block, inverse]) =>
new mir.IfContent({
keyword,
loc: node.loc,
condition: new mir.Not({ value: condition, loc: node.loc }),
block,
Expand All @@ -207,7 +210,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
.kw('each', {
assert(node): Result<{
value: ASTv2.ExpressionValueNode;
key: ASTv2.ExpressionValueNode | null;
key: ASTv2.CurlyArgument | null;
}> {
let { args } = node;

Expand All @@ -233,7 +236,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
}

let value = args.nth(0);
let key = args.get('key');
let key = args.getNode('key');

if (value === null) {
return Err(
Expand All @@ -247,22 +250,24 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Ok({ value, key });
},

translate({ node, state }, { value, key }): Result<mir.Each> {
translate({ node, keyword, state }, { value, key }): Result<mir.Each> {
let block = node.blocks.get('default');
let inverse = node.blocks.get('else');

let valueResult = visitExpr(value, state);
let keyResult = key ? visitExpr(key, state) : Ok(null);
let keyResult = key ? visitExpr(key.value, state) : Ok(null);

let blockResult = visitNamedBlock(block, state);
let inverseResult = inverse ? visitNamedBlock(inverse, state) : Ok(null);

return Result.all(valueResult, keyResult, blockResult, inverseResult).mapOk(
([value, key, block, inverse]) =>
([value, keyExpr, block, inverse]) =>
new mir.Each({
keyword,
loc: node.loc,
value,
key,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
key: keyExpr ? mir.CustomNamedArgument.from(key!, keyExpr) : null,
block,
inverse,
})
Expand Down Expand Up @@ -304,7 +309,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Ok({ positional });
},

translate({ node, state }, { positional }): Result<mir.Let> {
translate({ node, keyword, state }, { positional }): Result<mir.Let> {
let block = node.blocks.get('default');

let positionalResult = visitPositional(positional, state);
Expand All @@ -313,6 +318,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
return Result.all(positionalResult, blockResult).mapOk(
([positional, block]) =>
new mir.Let({
keyword,
loc: node.loc,
positional,
block,
Expand All @@ -333,15 +339,16 @@ export const BLOCK_KEYWORDS = keywords('Block')
}
},

translate({ node, state }, { named }): Result<mir.WithDynamicVars> {
translate({ node, keyword, state }, { named }): Result<mir.WithDynamicVars> {
let block = node.blocks.get('default');

let namedResult = visitNamedArguments(named, state);
let namedResult = visitCurlyNamedArguments(named, state);
let blockResult = visitNamedBlock(block, state);

return Result.all(namedResult, blockResult).mapOk(
([named, block]) =>
new mir.WithDynamicVars({
keyword,
loc: node.loc,
named,
block,
Expand All @@ -353,7 +360,7 @@ export const BLOCK_KEYWORDS = keywords('Block')
assert: assertCurryKeyword(CURRIED_COMPONENT),

translate(
{ node, state },
{ node, keyword, state },
{ definition, args }
): Result<mir.InvokeComponentKeyword | mir.InvokeResolvedComponentKeyword> {
let definitionResult = visitExpr(definition, state);
Expand All @@ -374,6 +381,7 @@ export const BLOCK_KEYWORDS = keywords('Block')

return Ok(
new mir.InvokeResolvedComponentKeyword({
keyword,
loc: node.loc,
definition: definition.value,
args,
Expand All @@ -384,6 +392,7 @@ export const BLOCK_KEYWORDS = keywords('Block')

return Ok(
new mir.InvokeComponentKeyword({
keyword,
loc: node.loc,
definition,
args,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Err } from '../../../shared/result';
export interface KeywordInfo<Match extends KeywordMatch> {
node: Match;
loc: SourceSpan;
keyword: SourceSpan;
state: NormalizationState;
args: ASTv2.CurlyArgs;
}
Expand Down Expand Up @@ -60,9 +61,10 @@ class KeywordImpl<
translate(node: KeywordMatches[K], state: NormalizationState): Result<Out> | null {
if (this.match(node)) {
const args = getKeywordArgs(node);
let param = this.delegate.assert({ node, loc: node.loc, state, args });
const keyword = node.resolved.loc;
let param = this.delegate.assert({ node, keyword, loc: node.loc, state, args });
return param.andThen((param) =>
this.delegate.translate({ node, loc: node.loc, state, args }, param)
this.delegate.translate({ node, keyword, loc: node.loc, state, args }, param)
);
} else {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ import type { CurriedType } from '@glimmer/interfaces';
import { CURRIED_COMPONENT, CURRIED_HELPER, CURRIED_MODIFIER } from '@glimmer/constants';
import { ASTv2, generateSyntaxError } from '@glimmer/syntax';

import type { NormalizationState } from '../../context';
import type { ContentKeywordMatch, KeywordDelegate, KeywordInfo } from '../impl';
import type {
ContentKeywordInfo,
ContentKeywordMatch,
KeywordDelegate,
KeywordInfo,
} from '../impl';

import { Err, Ok, Result } from '../../../../shared/result';
import * as mir from '../../../2-encoding/mir';
Expand Down Expand Up @@ -82,7 +86,7 @@ export function assertCurryKeyword(curriedType: CurriedType): ({

function translateCurryKeyword(curriedType: CurriedType) {
return (
{ node, state }: { node: ContentKeywordMatch; state: NormalizationState },
{ node, keyword, state }: ContentKeywordInfo,
{ definition, args }: { definition: ASTv2.ExpressionValueNode; args: ASTv2.CurlyArgs }
): Result<mir.Curry> => {
let definitionResult = visitExpr(definition, state);
Expand All @@ -91,6 +95,7 @@ function translateCurryKeyword(curriedType: CurriedType) {
return Result.all(definitionResult, argsResult).mapOk(
([definition, args]) =>
new mir.Curry({
keyword,
loc: node.loc,
curriedType,
definition,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import type { ASTv2 } from '@glimmer/syntax';
import { generateSyntaxError } from '@glimmer/syntax';

import type { Result } from '../../../../shared/result';
import type { NormalizationState } from '../../context';
import type { InvokeKeywordMatch, InvokeKeywordInfo, KeywordDelegate } from '../impl';
import type { InvokeKeywordInfo, InvokeKeywordMatch, KeywordDelegate } from '../impl';

import { Err, Ok } from '../../../../shared/result';
import * as mir from '../../../2-encoding/mir';
Expand Down Expand Up @@ -37,10 +36,12 @@ function assertGetDynamicVarKeyword({
}

function translateGetDynamicVarKeyword(
{ node, state }: { node: InvokeKeywordMatch; state: NormalizationState },
{ node, keyword, state }: InvokeKeywordInfo,
name: ASTv2.ExpressionValueNode
): Result<mir.GetDynamicVar> {
return visitExpr(name, state).mapOk((name) => new mir.GetDynamicVar({ name, loc: node.loc }));
return visitExpr(name, state).mapOk(
(name) => new mir.GetDynamicVar({ keyword, name, loc: node.loc })
);
}

export const getDynamicVarKeyword: KeywordDelegate<
Expand Down
Loading

0 comments on commit 0683762

Please sign in to comment.