Skip to content
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

implement inplace context #25

Merged
merged 1 commit into from
Aug 15, 2020
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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"pretty-quick": "^2.0.1",
"ts-jest": "^24.0.2",
"ts-node": "^8.3.0",
"typedraft": "0.2.2"
"typedraft": "0.0.0-31fb921"
},
"husky": {
"hooks": {
Expand Down
18 changes: 13 additions & 5 deletions src/code-object/module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type Draft = Array<ExportClassCode | MethodCode | LocalContext | InlineCo
* As we are only interested in the draft part of a module, then we need a way to return this "view" of module code.
*/
<ModuleCode /> +
function ToDraft(this: ModuleCode) {
function ToDraft(this: ModuleCode & IModuleCode) {
/**
* refresh and update bindings because DSL only transforms code
*/
Expand All @@ -23,8 +23,7 @@ export type Draft = Array<ExportClassCode | MethodCode | LocalContext | InlineCo
* traverse file and set path
*/
let draft: Draft = [];
traverse<{ _module: ModuleCode }>(
this.m_File,
this.Traverse<{ _module: ModuleCode }>(
{
Program(path) {
this._module.m_Path = path;
Expand All @@ -43,7 +42,6 @@ export type Draft = Array<ExportClassCode | MethodCode | LocalContext | InlineCo
}
},
},
null,
{ _module: this }
);

Expand All @@ -57,6 +55,16 @@ export type Draft = Array<ExportClassCode | MethodCode | LocalContext | InlineCo
return draft;
};

export interface IModuleCode {
Traverse<S>(visitor: TraverseOptions<S>, state: S): void;
}

<ModuleCode /> +
function Traverse<S>(this: ModuleCode, visitor: TraverseOptions<S>, state: S = null) {
this.m_File = ToFile(ToString(this.m_File));
traverse<S>(this.m_File, visitor, null, state);
};

/**
* ## Create draft
*/
Expand Down Expand Up @@ -136,5 +144,5 @@ import { ExportClassCode } from "./export-class";
import { MethodCode } from "./method";
import { LocalContext } from "./local-context";
import { ToFile, ToString } from "../common/utility";
import traverse, { NodePath, Node } from "@babel/traverse";
import traverse, { NodePath, Node, TraverseOptions } from "@babel/traverse";
import { InlineContext } from "./inline-context";
12 changes: 10 additions & 2 deletions src/core/transcriber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ export class Transcriber {
};

export interface IDSL {
Transcribe(
Transcribe?(
block: Array<Statement>,
path?: NodePath<FunctionDeclaration> | NodePath<BlockStatement>
): Array<Statement>;

InplaceTranscribe?(literal: NodePath<TemplateLiteral>): Expression;

m_Merge?: boolean;
}

Expand Down Expand Up @@ -135,7 +137,13 @@ export type TraverseLocalContextCallback = (context: LocalContext, name: string)
export type TraverseInlineContextCallback = (context: InlineContext) => void;
export type TraverseMethodCallback = (methods: Array<MethodCode>, class_name: string) => void;

import { Statement, FunctionDeclaration, BlockStatement } from "@babel/types";
import {
Statement,
FunctionDeclaration,
BlockStatement,
Expression,
TemplateLiteral,
} from "@babel/types";
import { NodePath } from "@babel/traverse";

import { ToString } from "../common/utility";
Expand Down
43 changes: 43 additions & 0 deletions src/plug-in/draft-plugin-inplace-context.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ITranscriber } from "../core/transcriber";
import { NodePath, Node } from "@babel/core";
import { StringLiteral, Identifier } from "@babel/types";

export class InplaceContextPlugin {
m_Transcriber: ITranscriber;
}

<InplaceContextPlugin /> +
function constructor(this: InplaceContextPlugin, transcriber: ITranscriber) {
this.m_Transcriber = transcriber;
};

<InplaceContextPlugin /> +
function Transcribe(this: InplaceContextPlugin) {
const transcriber = this.m_Transcriber;
transcriber.m_Module.Traverse({
TaggedTemplateExpression(path) {
const tag = path.get("tag");
if (!tag.isCallExpression()) {
return;
}

const callee = tag.get("callee") as NodePath<Identifier>;
const callee_name = callee.node.name as string;
if (callee_name !== "context" && callee_name !== "Λ") {
return;
}

const [arg] = (tag.get("arguments") as Array<NodePath<Node>>) as [
NodePath<StringLiteral>
];
const dsl_name = arg.node.value;

const dsl = transcriber.m_DSLMap.get(dsl_name);
if (!dsl) {
return;
}

path.replaceWith(dsl.InplaceTranscribe(path.get("quasi")));
},
});
};
23 changes: 23 additions & 0 deletions test/plug-in/__snapshots__/inplace-context.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`not inplace context no dsl 1`] = `
"const temp = Λ<number>(\\"math\\")\`
1+2
\`;"
`;

exports[`not inplace context not call expression 1`] = `
"context<number>\`
1+2
\`;"
`;

exports[`not inplace context not context or Λ 1`] = `
"whatever<number>(\\"math\\")\`
1+2
\`;"
`;

exports[`use inplace context as expression 1`] = `"const temp = \\"3\\";"`;

exports[`use inplace context as expression statement 1`] = `"\\"3\\";"`;
84 changes: 84 additions & 0 deletions test/plug-in/inplace-context.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { MakeDefaultTranscriber, IDSL } from "../../src";
import { InplaceContextPlugin } from "../../src/plug-in/draft-plugin-inplace-context";
import { NodePath } from "@babel/core";
import { TemplateLiteral, stringLiteral } from "@babel/types";

class Math implements IDSL {
InplaceTranscribe(literal: NodePath<TemplateLiteral>) {
return stringLiteral("3");
}
}

test("use inplace context as expression", () => {
//
const code = `
const temp = Λ<number>("math")\`
1+2
\`;
`;

const transcriber = MakeDefaultTranscriber(code);
transcriber.m_Plugins = [new InplaceContextPlugin(transcriber)];
transcriber.m_DSLMap.set("math", new Math());
const result = transcriber.Transcribe();
expect(result).toMatchSnapshot();
});

test("use inplace context as expression statement", () => {
//
const code = `
context<number>("math")\`
1+2
\`;
`;

const transcriber = MakeDefaultTranscriber(code);
transcriber.m_Plugins = [new InplaceContextPlugin(transcriber)];
transcriber.m_DSLMap.set("math", new Math());
const result = transcriber.Transcribe();
expect(result).toMatchSnapshot();
});

describe("not inplace context", () => {
test("not call expression", () => {
//
const code = `
context<number>\`
1+2
\`;
`;

const transcriber = MakeDefaultTranscriber(code);
transcriber.m_Plugins = [new InplaceContextPlugin(transcriber)];
const result = transcriber.Transcribe();
expect(result).toMatchSnapshot();
});

test("not context or Λ", () => {
//
const code = `
whatever<number>("math")\`
1+2
\`;
`;

const transcriber = MakeDefaultTranscriber(code);
transcriber.m_Plugins = [new InplaceContextPlugin(transcriber)];
const result = transcriber.Transcribe();
expect(result).toMatchSnapshot();
});

test("no dsl", () => {
//
const code = `
const temp = Λ<number>("math")\`
1+2
\`;
`;

const transcriber = MakeDefaultTranscriber(code);
transcriber.m_Plugins = [new InplaceContextPlugin(transcriber)];
const result = transcriber.Transcribe();
expect(result).toMatchSnapshot();
});
});