Skip to content

Commit

Permalink
Merge pull request #1046 from glimmerjs/compiler-types
Browse files Browse the repository at this point in the history
[CLEANUP] Fix compiler typing
  • Loading branch information
krisselden authored Feb 17, 2020
2 parents 0845927 + 59b1276 commit 11cc83b
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 121 deletions.
48 changes: 11 additions & 37 deletions packages/@glimmer/interfaces/lib/compile/wire-format.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,43 +49,17 @@ export const enum SexpOpcodes {
Concat = 32,
}

export interface SexpOpcodeMap {
[index: number]: TupleSyntax;

[SexpOpcodes.Append]: Statements.Append;
[SexpOpcodes.Comment]: Statements.Comment;
[SexpOpcodes.Modifier]: Statements.Modifier;
[SexpOpcodes.Block]: Statements.Block;
[SexpOpcodes.Component]: Statements.Component;
[SexpOpcodes.OpenElement]: Statements.OpenElement;
[SexpOpcodes.FlushElement]: Statements.FlushElement;
[SexpOpcodes.CloseElement]: Statements.CloseElement;
[SexpOpcodes.StaticAttr]: Statements.StaticAttr;
[SexpOpcodes.DynamicAttr]: Statements.DynamicAttr;
[SexpOpcodes.ComponentAttr]: Statements.ComponentAttr;
[SexpOpcodes.AttrSplat]: Statements.AttrSplat;
[SexpOpcodes.Yield]: Statements.Yield;
[SexpOpcodes.Partial]: Statements.Partial;

[SexpOpcodes.DynamicArg]: Statements.DynamicArg;
[SexpOpcodes.StaticArg]: Statements.StaticArg;
[SexpOpcodes.StaticComponentAttr]: Statements.StaticComponentAttr;
[SexpOpcodes.TrustingDynamicAttr]: Statements.TrustingAttr;
[SexpOpcodes.TrustingComponentAttr]: Statements.TrustingComponentAttr;
[SexpOpcodes.Debugger]: Statements.Debugger;

// Expressions

[SexpOpcodes.GetSymbol]: Expressions.GetSymbol;
[SexpOpcodes.GetFree]: Expressions.GetFree;
[SexpOpcodes.GetContextualFree]: Expressions.GetContextualFree;
[SexpOpcodes.GetPath]: Expressions.GetPath;
[SexpOpcodes.HasBlock]: Expressions.HasBlock;
[SexpOpcodes.HasBlockParams]: Expressions.HasBlockParams;
[SexpOpcodes.Undefined]: Expressions.Undefined;
[SexpOpcodes.Call]: Expressions.Helper;
[SexpOpcodes.Concat]: Expressions.Concat;
}
export type StatementSexpOpcode = Statement[0];
export type StatementSexpOpcodeMap = {
[TSexpOpcode in Statement[0]]: Extract<Statement, { 0: TSexpOpcode }>;
};
export type ExpressionSexpOpcode = TupleExpression[0];
export type ExpressionSexpOpcodeMap = {
[TSexpOpcode in TupleExpression[0]]: Extract<TupleExpression, { 0: TSexpOpcode }>;
};

export interface SexpOpcodeMap extends ExpressionSexpOpcodeMap, StatementSexpOpcodeMap {}
export type SexpOpcode = keyof SexpOpcodeMap;

export namespace Core {
export type Expression = Expressions.Expression;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ import { YieldBlock, PushSymbolTable, InvokeStaticBlock, PushYieldableBlock } fr
import { Replayable } from './conditional';
import { EMPTY_ARRAY } from '@glimmer/util';
import { op } from '../encoder';
import { ATTRS_BLOCK } from '../../syntax/compilers';
import { UNHANDLED, NONE } from '../../syntax/concat';
import { compilableBlock } from '../../compilable-template';
import { NamedBlocksImpl } from '../../utils';
import { MacroContext } from '../../syntax/macros';
import { MINIMAL_CAPABILITIES } from '../delegate';

export const ATTRS_BLOCK = '&attrs';

export type Block = () => CompileActions;

interface AnyComponent {
Expand Down
93 changes: 16 additions & 77 deletions packages/@glimmer/opcode-compiler/lib/syntax/compilers.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,27 @@
import {
CompileTimeResolverDelegate,
ContainingMetadata,
SexpOpcodeMap,
SexpOpcodes,
StatementCompileActions,
WireFormat,
ExpressionCompileActions,
TupleSyntax,
Dict,
} from '@glimmer/interfaces';
import { assert, dict } from '@glimmer/util';
import { ContainingMetadata, SexpOpcode, SexpOpcodeMap } from '@glimmer/interfaces';
import { assert } from '@glimmer/util';

export type RegisteredStatementSyntax = StatementCompilerFunction<WireFormat.Statement>;

export type RegisteredExpressionSyntax = LeafCompilerFunction<WireFormat.TupleExpression>;

// TODO: Is leaf vs. statement vs. expression the right split?
// TODO: Either way, consolidate the naming

export type RegisteredSyntax = RegisteredStatementSyntax | RegisteredExpressionSyntax;

export type LeafCompilerFunction<T extends TupleSyntax> = (
sexp: T,
meta: ContainingMetadata
) => ExpressionCompileActions;

export type StatementCompilerFunction<T extends WireFormat.Statement> = (
sexp: T,
export type CompilerFunction<TSexp, TCompileActions> = (
sexp: TSexp,
meta: ContainingMetadata
) => StatementCompileActions;
) => TCompileActions;

export interface StatementCompilationContext {
meta: ContainingMetadata;
resolver: CompileTimeResolverDelegate;
}

abstract class Compilers<U extends RegisteredSyntax> {
protected names: Dict<number> = dict();
protected abstract funcs: U[];

add<N extends SexpOpcodes>(name: N, func: LeafCompilerFunction<SexpOpcodeMap[N]>): void {
this.funcs.push(func as U);
this.names[name] = this.funcs.length - 1;
}
}
export class Compilers<TSexpOpcodes extends SexpOpcode, TCompileActions> {
private names: {
[name: number]: number;
} = {};

export class StatementCompilers extends Compilers<RegisteredStatementSyntax> {
protected funcs: Array<
StatementCompilerFunction<SexpOpcodeMap[SexpOpcodes] & WireFormat.Statement>
> = [];
private funcs: CompilerFunction<any, TCompileActions>[] = [];

add<T extends SexpOpcodes>(
name: T,
func: StatementCompilerFunction<SexpOpcodeMap[T] & WireFormat.Statement>
add<TSexpOpcode extends TSexpOpcodes>(
name: TSexpOpcode,
func: CompilerFunction<SexpOpcodeMap[TSexpOpcode], TCompileActions>
): void {
// TODO: This is not ideal and could probably miss bugs. However, getting the type inference
// to work correctly here is critical to the correctness of expressions.ts and statements.ts
// so it seems worth it for now.
this.funcs.push(func as any);
this.names[name] = this.funcs.length - 1;
this.names[name] = this.funcs.push(func) - 1;
}

compile(sexp: WireFormat.Statement, meta: ContainingMetadata): StatementCompileActions {
let name: number = sexp[0];
let index = this.names[name];
let func = this.funcs[index];
assert(!!func, `expected an implementation for ${sexp[0]}`);

return func(sexp, meta);
}
}

export type SimpleCompilerFunction<T extends TupleSyntax> = (
sexp: T,
meta: ContainingMetadata
) => ExpressionCompileActions;

export const ATTRS_BLOCK = '&attrs';

export class ExpressionCompilers extends Compilers<RegisteredExpressionSyntax> {
protected funcs: RegisteredExpressionSyntax[] = [];

compile(sexp: WireFormat.TupleExpression, meta: ContainingMetadata): ExpressionCompileActions {
let name: number = sexp![0];
compile(sexp: SexpOpcodeMap[TSexpOpcodes], meta: ContainingMetadata): TCompileActions {
let name = sexp[0];
let index = this.names[name];
let func = this.funcs[index];
assert(!!func, `expected an implementation for ${sexp[0]}`);
Expand Down
6 changes: 4 additions & 2 deletions packages/@glimmer/opcode-compiler/lib/syntax/expressions.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { ExpressionCompilers } from './compilers';
import { Compilers } from './compilers';
import {
SexpOpcodes,
ResolveHandle,
Op,
Expressions,
ExpressionSexpOpcode,
ExpressionCompileActions,
ContainingMetadata,
} from '@glimmer/interfaces';
import { op } from '../opcode-builder/encoder';
import { Call, PushPrimitiveReference } from '../opcode-builder/helpers/vm';
import { curryComponent } from '../opcode-builder/helpers/components';
import { expectString } from '../utils';

export const EXPRESSIONS = new ExpressionCompilers();
export const EXPRESSIONS = new Compilers<ExpressionSexpOpcode, ExpressionCompileActions>();

EXPRESSIONS.add(SexpOpcodes.Concat, ([, parts]) => {
let out = [];
Expand Down
6 changes: 4 additions & 2 deletions packages/@glimmer/opcode-compiler/lib/syntax/statements.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { StatementCompilers } from './compilers';
import { Compilers } from './compilers';
import {
SexpOpcodes,
Op,
ResolveHandle,
MachineOp,
HighLevelResolutionOpcode,
StatementSexpOpcode,
StatementCompileActions,
} from '@glimmer/interfaces';
import { op } from '../opcode-builder/encoder';
import { templateMeta, strArray, arr } from '../opcode-builder/operands';
Expand All @@ -15,7 +17,7 @@ import { EMPTY_ARRAY } from '@glimmer/util';
import { $sp } from '@glimmer/vm';
import { expectString } from '../utils';

export const STATEMENTS = new StatementCompilers();
export const STATEMENTS = new Compilers<StatementSexpOpcode, StatementCompileActions>();

STATEMENTS.add(SexpOpcodes.Comment, sexp => op(Op.Comment, sexp[1]));
STATEMENTS.add(SexpOpcodes.CloseElement, () => op(Op.CloseElement));
Expand Down
3 changes: 1 addition & 2 deletions packages/@glimmer/opcode-compiler/lib/wrapped-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import {

import { templateCompilationContext } from './opcode-builder/context';
import { meta } from './opcode-builder/helpers/shared';
import { WrappedComponent } from './opcode-builder/helpers/components';
import { ATTRS_BLOCK, WrappedComponent } from './opcode-builder/helpers/components';
import { LOCAL_SHOULD_LOG } from '@glimmer/local-debug-flags';
import { debugCompiler } from './compiler';
import { ATTRS_BLOCK } from './syntax/compilers';
import { concatStatements } from './syntax/concat';
import { patchStdlibs } from '@glimmer/program';

Expand Down

0 comments on commit 11cc83b

Please sign in to comment.