added options of inlining _List_fromArray calls with object literals

This commit is contained in:
Simon 2020-07-25 21:49:20 -07:00
parent d831907cc5
commit 6122ce9dc0
4 changed files with 74 additions and 23 deletions

5
package-lock.json generated
View File

@ -9471,6 +9471,11 @@
"yn": "3.1.1"
}
},
"ts-union": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ts-union/-/ts-union-2.2.1.tgz",
"integrity": "sha512-GLHuuu+N+n3mHY8/XzHUbuXf64Xy2nzYUa1/8rNCtkP6pD3mTiSM5OIyxV81ecT33S3i7lbVWdvCtyFmS8rplw=="
},
"tsconfig-paths": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",

View File

@ -44,6 +44,7 @@
},
"dependencies": {
"tree-sitter": "^0.16.1",
"tree-sitter-elm": "^2.7.9"
"tree-sitter-elm": "^2.7.9",
"ts-union": "^2.2.1"
}
}

View File

@ -1,29 +1,53 @@
import ts from 'typescript';
import { Union, of } from 'ts-union';
import { Mode } from './types';
// `
// var _List_Nil = { $: "[]" };
// debug
// function _List_Cons(hd, tl) {
// return { $: "::", a: hd, b: tl };
// const f = () => {
// var _List_Nil = { $: '[]' };
// function _List_Cons<T>(hd: T, tl: T | typeof _List_Nil) {
// return { $: '::', a: hd, b: tl };
// }
// var _List_cons = F2(_List_Cons);
// // var _List_cons = F2(_List_Cons);
// function _List_fromArray(arr) {
// function _List_fromArray<T>(arr: T[]) {
// var out = _List_Nil;
// for (var i = arr.length; i--; ) {
// out = _List_Cons(arr[i], out);
// }
// return out;
// }
// `;
// `
// _List_fromArray([
// "a",
// "b",
// "c",
// ])
// `;
// const res = _List_fromArray(['a', 'b', 'c']);
// console.log(res);
// };
// f();
// prod
// var _List_Nil = { $: 0 };
// var _List_Nil_UNUSED = { $: '[]' };
// function _List_Cons(hd, tl) {
// return { $: 1, a: hd, b: tl };
// }
const listElementMarker = (mode: Mode): ts.Expression =>
mode === Mode.Dev
? ts.createStringLiteral('::')
: ts.createNumericLiteral('1');
export const InlineMode = Union({
UsingConsFunc: of(null),
UsingLiteralObjects: of<Mode>(),
});
export type InlineMode = typeof InlineMode.T;
const LIST_FROM_ARRAY_F_NAME = '_List_fromArray';
const LIST_NIL_NAME = '_List_Nil';
@ -32,14 +56,26 @@ const LIST_CONS_F_NAME = '_List_cons';
const listNil = ts.createIdentifier(LIST_NIL_NAME);
const listConsCall = ts.createIdentifier(LIST_CONS_F_NAME);
const appendToFront = (
expression: ts.Expression,
list: ts.Expression
const appendToFront = (inlineMode: InlineMode) => (
list: ts.Expression,
element: ts.Expression
): ts.Expression => {
return ts.createCall(listConsCall, undefined, [expression, list]);
return InlineMode.match(inlineMode, {
UsingConsFunc: (): ts.Expression =>
ts.createCall(listConsCall, undefined, [element, list]),
UsingLiteralObjects: mode =>
ts.createObjectLiteral([
ts.createPropertyAssignment('$', listElementMarker(mode)),
ts.createPropertyAssignment('a', element),
ts.createPropertyAssignment('b', list),
]),
});
};
export const createInlineListFromArrayTransformer = (): ts.TransformerFactory<ts.SourceFile> => context => {
export const createInlineListFromArrayTransformer = (
inlineMode: InlineMode
): ts.TransformerFactory<ts.SourceFile> => context => {
return sourceFile => {
const visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
// detects [exp](..)
@ -55,7 +91,10 @@ export const createInlineListFromArrayTransformer = (): ts.TransformerFactory<ts
// detects _List_fromArray([..])
if (ts.isArrayLiteralExpression(arrayLiteral)) {
return arrayLiteral.elements.reduceRight(appendToFront, listNil);
return arrayLiteral.elements.reduceRight(
appendToFront(inlineMode),
listNil
);
}
}
}

View File

@ -10,7 +10,10 @@ import {
} from './experiments/inlineWrappedFunctions';
import { Mode } from './experiments/types';
import { createInlineListFromArrayTransformer } from './experiments/inlineListFromArray';
import {
createInlineListFromArrayTransformer,
InlineMode,
} from './experiments/inlineListFromArray';
const elmOutput = `
var $elm$core$Maybe$Nothing = {$: 'Nothing'};
@ -90,7 +93,10 @@ console.log(printer.printFile(sourceWithInlinedFuntioncs));
console.log(
'----------AFTER INLINE _List_fromArray TRANSFORM ----------------'
);
const inlineListFromArrayCalls = createInlineListFromArrayTransformer();
const inlineListFromArrayCalls = createInlineListFromArrayTransformer(
InlineMode.UsingLiteralObjects(Mode.Prod)
// InlineMode.UsingConsFunc
);
const [sourceWithInlinedListFromArr] = ts.transform(
sourceWithInlinedFuntioncs,
[inlineListFromArrayCalls]