mirror of
https://github.com/mdgriffith/elm-optimize-level-2.git
synced 2024-12-01 19:35:08 +03:00
Merge branch 'master' of https://github.com/mdgriffith/elm-optimize
This commit is contained in:
commit
d831907cc5
68
src/experiments/inlineListFromArray.ts
Normal file
68
src/experiments/inlineListFromArray.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import ts from 'typescript';
|
||||
|
||||
// `
|
||||
// var _List_Nil = { $: "[]" };
|
||||
|
||||
// function _List_Cons(hd, tl) {
|
||||
// return { $: "::", a: hd, b: tl };
|
||||
// }
|
||||
|
||||
// var _List_cons = F2(_List_Cons);
|
||||
|
||||
// function _List_fromArray(arr) {
|
||||
// var out = _List_Nil;
|
||||
// for (var i = arr.length; i--; ) {
|
||||
// out = _List_Cons(arr[i], out);
|
||||
// }
|
||||
// return out;
|
||||
// }
|
||||
// `;
|
||||
// `
|
||||
// _List_fromArray([
|
||||
// "a",
|
||||
// "b",
|
||||
// "c",
|
||||
// ])
|
||||
// `;
|
||||
|
||||
const LIST_FROM_ARRAY_F_NAME = '_List_fromArray';
|
||||
const LIST_NIL_NAME = '_List_Nil';
|
||||
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
|
||||
): ts.Expression => {
|
||||
return ts.createCall(listConsCall, undefined, [expression, list]);
|
||||
};
|
||||
|
||||
export const createInlineListFromArrayTransformer = (): ts.TransformerFactory<ts.SourceFile> => context => {
|
||||
return sourceFile => {
|
||||
const visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
|
||||
// detects [exp](..)
|
||||
if (ts.isCallExpression(node)) {
|
||||
const expression = node.expression;
|
||||
// detects _List_fromArray(..)
|
||||
if (
|
||||
ts.isIdentifier(expression) &&
|
||||
expression.text === LIST_FROM_ARRAY_F_NAME &&
|
||||
node.arguments.length === 1
|
||||
) {
|
||||
const [arrayLiteral] = node.arguments;
|
||||
|
||||
// detects _List_fromArray([..])
|
||||
if (ts.isArrayLiteralExpression(arrayLiteral)) {
|
||||
return arrayLiteral.elements.reduceRight(appendToFront, listNil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ts.visitEachChild(node, visitor, context);
|
||||
};
|
||||
|
||||
return ts.visitNode(sourceFile, visitor);
|
||||
};
|
||||
};
|
4
src/experiments/types.ts
Normal file
4
src/experiments/types.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export enum Mode {
|
||||
Prod = 'prod',
|
||||
Dev = 'dev',
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
import ts from 'typescript';
|
||||
import { Mode } from './types';
|
||||
|
||||
export type VariantReplacement = {
|
||||
symbolName: string;
|
||||
variantName: string;
|
||||
variantIndex: number;
|
||||
maximumNumberOfArgs: number;
|
||||
numberOfArgs: number;
|
||||
};
|
||||
@ -10,17 +12,22 @@ export type VariantReplacement = {
|
||||
// TODO fill a proper array
|
||||
const argNames = ['a', 'b', 'c', 'd', 'e'];
|
||||
|
||||
const createVariantObjectLiteral = ({
|
||||
variantName,
|
||||
maximumNumberOfArgs,
|
||||
numberOfArgs,
|
||||
}: {
|
||||
variantName: string;
|
||||
maximumNumberOfArgs: number;
|
||||
numberOfArgs: number;
|
||||
}): ts.ObjectLiteralExpression => {
|
||||
const createVariantObjectLiteral = (
|
||||
{
|
||||
variantName,
|
||||
maximumNumberOfArgs,
|
||||
numberOfArgs,
|
||||
variantIndex,
|
||||
}: VariantReplacement,
|
||||
mode: Mode
|
||||
): ts.ObjectLiteralExpression => {
|
||||
return ts.createObjectLiteral([
|
||||
ts.createPropertyAssignment('$', ts.createStringLiteral(variantName)),
|
||||
ts.createPropertyAssignment(
|
||||
'$',
|
||||
mode === Mode.Dev
|
||||
? ts.createStringLiteral(variantName)
|
||||
: ts.createNumericLiteral(variantIndex.toString())
|
||||
),
|
||||
// existing arguments
|
||||
...argNames
|
||||
.slice(0, numberOfArgs)
|
||||
@ -32,11 +39,11 @@ const createVariantObjectLiteral = ({
|
||||
]);
|
||||
};
|
||||
|
||||
const createCtorVariant = ({
|
||||
variantName,
|
||||
maximumNumberOfArgs,
|
||||
numberOfArgs,
|
||||
}: VariantReplacement): ts.Expression => {
|
||||
const createCtorVariant = (
|
||||
replacement: VariantReplacement,
|
||||
mode: Mode
|
||||
): ts.Expression => {
|
||||
const { numberOfArgs } = replacement;
|
||||
const funcExpression = ts.createArrowFunction(
|
||||
undefined,
|
||||
undefined,
|
||||
@ -55,11 +62,7 @@ const createCtorVariant = ({
|
||||
),
|
||||
undefined,
|
||||
undefined,
|
||||
createVariantObjectLiteral({
|
||||
variantName,
|
||||
maximumNumberOfArgs,
|
||||
numberOfArgs,
|
||||
})
|
||||
createVariantObjectLiteral(replacement, mode)
|
||||
);
|
||||
|
||||
if (numberOfArgs > 1) {
|
||||
@ -75,7 +78,8 @@ const createCtorVariant = ({
|
||||
};
|
||||
|
||||
export const createCustomTypesTransformer = (
|
||||
replacements: VariantReplacement[]
|
||||
replacements: VariantReplacement[],
|
||||
mode: Mode
|
||||
): ts.TransformerFactory<ts.SourceFile> => context => {
|
||||
return sourceFile => {
|
||||
const visitor = (node: ts.Node): ts.Node => {
|
||||
@ -83,16 +87,11 @@ export const createCustomTypesTransformer = (
|
||||
for (const replacement of replacements) {
|
||||
if (node.name.text === replacement.symbolName) {
|
||||
if (replacement.numberOfArgs === 0) {
|
||||
const { variantName, maximumNumberOfArgs } = replacement;
|
||||
return ts.updateVariableDeclaration(
|
||||
node,
|
||||
node.name,
|
||||
node.type,
|
||||
createVariantObjectLiteral({
|
||||
variantName,
|
||||
maximumNumberOfArgs,
|
||||
numberOfArgs: 0,
|
||||
})
|
||||
createVariantObjectLiteral(replacement, mode)
|
||||
);
|
||||
}
|
||||
|
||||
@ -100,7 +99,7 @@ export const createCustomTypesTransformer = (
|
||||
node,
|
||||
node.name,
|
||||
node.type,
|
||||
createCtorVariant(replacement)
|
||||
createCtorVariant(replacement, mode)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
26
src/index.ts
26
src/index.ts
@ -8,6 +8,9 @@ import {
|
||||
FuncSplit,
|
||||
createFuncInlineTransformer,
|
||||
} from './experiments/inlineWrappedFunctions';
|
||||
import { Mode } from './experiments/types';
|
||||
|
||||
import { createInlineListFromArrayTransformer } from './experiments/inlineListFromArray';
|
||||
|
||||
const elmOutput = `
|
||||
var $elm$core$Maybe$Nothing = {$: 'Nothing'};
|
||||
@ -22,6 +25,8 @@ var $author$project$Main$Three = F3(
|
||||
});
|
||||
|
||||
var _v1 = A3($author$project$Main$Three, a, b, c);
|
||||
|
||||
_List_fromArray(['a', 'b', 'c']);
|
||||
`;
|
||||
|
||||
const source = ts.createSourceFile('elm.js', elmOutput, ts.ScriptTarget.ES2018);
|
||||
@ -31,6 +36,7 @@ const replacements: VariantReplacement[] = [
|
||||
symbolName: '$elm$core$Maybe$Nothing',
|
||||
variantName: 'Nothing',
|
||||
maximumNumberOfArgs: 1,
|
||||
variantIndex: 1,
|
||||
numberOfArgs: 0,
|
||||
},
|
||||
|
||||
@ -38,17 +44,22 @@ const replacements: VariantReplacement[] = [
|
||||
symbolName: '$elm$core$Maybe$Just',
|
||||
variantName: 'Just',
|
||||
numberOfArgs: 1,
|
||||
variantIndex: 0,
|
||||
maximumNumberOfArgs: 2,
|
||||
},
|
||||
{
|
||||
symbolName: '$author$project$Main$Three',
|
||||
variantName: 'Three',
|
||||
numberOfArgs: 3,
|
||||
variantIndex: 100500,
|
||||
maximumNumberOfArgs: 4,
|
||||
},
|
||||
];
|
||||
|
||||
const customTypeTransformer = createCustomTypesTransformer(replacements);
|
||||
const customTypeTransformer = createCustomTypesTransformer(
|
||||
replacements,
|
||||
Mode.Prod
|
||||
);
|
||||
const [newFile] = ts.transform(source, [customTypeTransformer]).transformed;
|
||||
|
||||
const printer = ts.createPrinter();
|
||||
@ -68,10 +79,21 @@ const [sourceWithSplittedFunctions] = ts.transform(newFile, [
|
||||
console.log(printer.printFile(sourceWithSplittedFunctions));
|
||||
console.log(collectedSplits);
|
||||
|
||||
console.log('----------AFTER SPLIT TRANSFORM ----------------');
|
||||
console.log('----------AFTER INLINE A(n) TRANSFORM ----------------');
|
||||
const funcInlineTransformer = createFuncInlineTransformer(collectedSplits);
|
||||
const [sourceWithInlinedFuntioncs] = ts.transform(sourceWithSplittedFunctions, [
|
||||
funcInlineTransformer,
|
||||
]).transformed;
|
||||
|
||||
console.log(printer.printFile(sourceWithInlinedFuntioncs));
|
||||
|
||||
console.log(
|
||||
'----------AFTER INLINE _List_fromArray TRANSFORM ----------------'
|
||||
);
|
||||
const inlineListFromArrayCalls = createInlineListFromArrayTransformer();
|
||||
const [sourceWithInlinedListFromArr] = ts.transform(
|
||||
sourceWithInlinedFuntioncs,
|
||||
[inlineListFromArrayCalls]
|
||||
).transformed;
|
||||
|
||||
console.log(printer.printFile(sourceWithInlinedListFromArr));
|
||||
|
Loading…
Reference in New Issue
Block a user