mirror of
https://github.com/mdgriffith/elm-optimize-level-2.git
synced 2024-11-29 12:46:32 +03:00
206 lines
4.8 KiB
TypeScript
206 lines
4.8 KiB
TypeScript
import { transformCode } from './inlineWrappedFunctions.test';
|
|
import { createPassUnwrappedFunctionsTransformer } from '../src/transforms/passUnwrappedFunctions';
|
|
import { createInlineContext } from '../src/transforms/inlineWrappedFunctions';
|
|
|
|
test('it can unwrap lambdas in place ', () => {
|
|
const initialCode = `
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
};
|
|
|
|
f(F2(function (a,b) {return a + b;}), 1, 2);
|
|
`;
|
|
|
|
const expectedOutputCode = `
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
}, f_unwrapped = function(func, a, b) {
|
|
return func(a, b)
|
|
};
|
|
|
|
f_unwrapped(function (a,b) {return a + b;}, 1, 2);
|
|
`;
|
|
|
|
const { actual, expected } = transformCode(
|
|
initialCode,
|
|
expectedOutputCode,
|
|
createPassUnwrappedFunctionsTransformer(() => undefined)
|
|
);
|
|
|
|
expect(actual).toBe(expected);
|
|
});
|
|
|
|
test('it can deal with nesting too', () => {
|
|
const initialCode = `
|
|
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
};
|
|
|
|
var val = someFunc(
|
|
f(F2(function (a,b) {
|
|
return f(F2(function (c,d) {return 0} ), a, b)
|
|
}), 1,2)
|
|
`;
|
|
|
|
const expectedOutputCode = `
|
|
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
}, f_unwrapped = function(func, a, b) {
|
|
return func(a, b)
|
|
};
|
|
|
|
var val = someFunc(
|
|
f_unwrapped(function (a,b) {
|
|
return f_unwrapped(function (c,d) {return 0}, a, b)
|
|
}, 1,2)
|
|
`;
|
|
|
|
const { actual, expected } = transformCode(
|
|
initialCode,
|
|
expectedOutputCode,
|
|
createPassUnwrappedFunctionsTransformer(() => undefined)
|
|
);
|
|
|
|
expect(actual).toBe(expected);
|
|
});
|
|
test('it can unwrap lambdas in place ', () => {
|
|
const initialCode = `
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
};
|
|
|
|
f(F2(function (a,b) {return a + b;}), 1, 2);
|
|
`;
|
|
|
|
const expectedOutputCode = `
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
}, f_unwrapped = function(func, a, b) {
|
|
return func(a, b)
|
|
};
|
|
|
|
f_unwrapped(function (a,b) {return a + b;}, 1, 2);
|
|
`;
|
|
|
|
const { actual, expected } = transformCode(
|
|
initialCode,
|
|
expectedOutputCode,
|
|
createPassUnwrappedFunctionsTransformer(() => undefined)
|
|
);
|
|
|
|
expect(actual).toBe(expected);
|
|
});
|
|
|
|
test('it properly replaces names in recursion and all uses of the passed function', () => {
|
|
const initialCode = `
|
|
var g = function(func) {
|
|
return A2(func, 1, 1);
|
|
};
|
|
|
|
var f = function(func, a, b) {
|
|
return f(func, A2(func, a, a), A2(func, b, b)) + g(func);
|
|
};
|
|
|
|
|
|
f(F2(function (a,b) {return a + b;}), 1, 2);
|
|
`;
|
|
|
|
const expectedOutputCode = `
|
|
var g = function(func) {
|
|
return A2(func, 1, 1);
|
|
}, g_unwrapped = function(func) {
|
|
return func(1, 1);
|
|
};
|
|
|
|
var f = function(func, a, b) {
|
|
return f(func, A2(func, a, a), A2(func, b, b)) + g(func);
|
|
}, f_unwrapped = function(func, a, b) {
|
|
return f_unwrapped(func, func(a, a), func(b, b)) + g_unwrapped(func);
|
|
};
|
|
|
|
f_unwrapped(function (a,b) {return a + b;}, 1, 2);
|
|
`;
|
|
|
|
const { actual, expected } = transformCode(
|
|
initialCode,
|
|
expectedOutputCode,
|
|
createPassUnwrappedFunctionsTransformer(() => undefined)
|
|
);
|
|
|
|
expect(actual).toBe(expected);
|
|
});
|
|
|
|
test('it bails out if there is a call with different arity', () => {
|
|
const initialCodeWithA = `
|
|
var f = function(func, a, b) {
|
|
A3(func, a, b, 1);
|
|
A2(func, a, b);
|
|
};
|
|
|
|
f(F3(function (a,b,c) {return a + b + c;}), 1, 2);
|
|
`;
|
|
|
|
const initialCodeWithDirectCall = `
|
|
var f = function(func, a, b) {
|
|
A3(func, a, b, func(a));
|
|
};
|
|
|
|
f(F3(function (a,b,c) {return a + b + c;}), 1, 2);
|
|
`;
|
|
|
|
const resA = transformCode(
|
|
initialCodeWithA,
|
|
initialCodeWithA,
|
|
createPassUnwrappedFunctionsTransformer(() => undefined)
|
|
);
|
|
|
|
expect(resA.actual).toBe(resA.expected);
|
|
|
|
const resDirectCall = transformCode(
|
|
initialCodeWithDirectCall,
|
|
initialCodeWithDirectCall,
|
|
createPassUnwrappedFunctionsTransformer(() => undefined)
|
|
);
|
|
|
|
expect(resDirectCall.actual).toBe(resDirectCall.expected);
|
|
});
|
|
|
|
// commented out for now
|
|
test('it can pass raw functions if there is one registered', () => {
|
|
const initialCode = `
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
};
|
|
|
|
f(wrappedFunc, 1, 2);
|
|
`;
|
|
|
|
const expectedOutputCode = `
|
|
var f = function(func, a, b) {
|
|
return A2(func, a, b)
|
|
}, f_unwrapped = function(func, a, b) {
|
|
return func(a, b)
|
|
};
|
|
|
|
f_unwrapped(wrappedFunc_fn, 1, 2);
|
|
`;
|
|
|
|
const inlineContext = createInlineContext();
|
|
|
|
inlineContext.splits.set('wrappedFunc', {
|
|
arity: 2,
|
|
rawLambdaName: 'wrappedFunc_fn',
|
|
type: 'raw_func',
|
|
});
|
|
|
|
const { actual, expected } = transformCode(
|
|
initialCode,
|
|
expectedOutputCode,
|
|
createPassUnwrappedFunctionsTransformer(() => inlineContext)
|
|
);
|
|
|
|
expect(actual).toBe(expected);
|
|
});
|