Skip to content

Commit

Permalink
feat: add support for funciton expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
pcriadoperez committed Sep 11, 2024
1 parent 34e762c commit a917edc
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 5 deletions.
21 changes: 16 additions & 5 deletions src/baseTranspiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ class BaseTranspiler {
requiresParameterType;
supportsFalsyOrTruthyValues;
requiresCallExpressionCast;
removeVariableDeclarationForFunctionExpression;
includeFunctionNameInFunctionExpressionDeclaration;
id;

constructor(config) {
Expand All @@ -198,6 +200,8 @@ class BaseTranspiler {
this.requiresParameterType = false;
this.supportsFalsyOrTruthyValues = true;
this.requiresCallExpressionCast = false;
this.removeVariableDeclarationForFunctionExpression = true;
this.includeFunctionNameInFunctionExpressionDeclaration = true;
this.initOperators();
}

Expand Down Expand Up @@ -818,7 +822,7 @@ class BaseTranspiler {
}

printFunctionDefinition(node, identation) {
let name = node.name.escapedText;
let name = node.name?.escapedText ?? "";
name = this.transformFunctionNameIfNeeded(name);

const parsedArgs = node.parameters.map(param => this.printParameter(param)).join(", ");
Expand All @@ -830,11 +834,14 @@ class BaseTranspiler {
returnType = returnType ? returnType + " " : returnType;

const fnKeyword = this.FUNCTION_TOKEN ? this.FUNCTION_TOKEN + " " : "";
if (!fnKeyword){
if (!fnKeyword && ts.isFunctionDeclaration(node)){
modifiers = modifiers + "public ";
}
const functionDef = this.getIden(identation) + modifiers + returnType + fnKeyword + name
+ "(" + parsedArgs + ")";
let functionDef = this.getIden(identation) + modifiers + returnType + fnKeyword;
if (this.includeFunctionNameInFunctionExpressionDeclaration || !ts.isFunctionExpression(node)) {
functionDef += name;
}
functionDef += "(" + parsedArgs + ")";

return functionDef;
}
Expand Down Expand Up @@ -926,6 +933,10 @@ class BaseTranspiler {
printVariableDeclarationList(node,identation) {
const declaration = node.declarations[0];
const varToken = this.VAR_TOKEN ? this.VAR_TOKEN + " ": "";

if (this.removeVariableDeclarationForFunctionExpression && (ts.isFunctionExpression(declaration.initializer) || ts.isArrowFunction(declaration.initializer))) {
return this.printNode(declaration.initializer, identation).trimEnd();
}
// const name = declaration.name.escapedText;
const parsedValue = (declaration.initializer) ? this.printNode(declaration.initializer, identation) : this.NULL_TOKEN;
return this.getIden(identation) + varToken + this.printNode(declaration.name) + " = " + parsedValue.trim();
Expand Down Expand Up @@ -1680,7 +1691,7 @@ class BaseTranspiler {
return this.printExpressionStatement(node, identation);
} else if(ts.isBlock(node)) {
return this.printBlock(node, identation);
} else if (ts.isFunctionDeclaration(node)){
} else if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)){
return this.printFunctionDeclaration(node, identation);
} else if (ts.isClassDeclaration(node)) {
return this.printClass(node, identation);
Expand Down
3 changes: 3 additions & 0 deletions src/csharpTranspiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,9 @@ export class CSharpTranspiler extends BaseTranspiler {
const declaration = node.declarations[0];
// const name = declaration.name.escapedText;

if (this.removeVariableDeclarationForFunctionExpression && ts.isFunctionExpression(declaration.initializer)) {
return this.printNode(declaration.initializer, identation).trimEnd();
}
// handle array binding : input: const [a,b] = this.method()
// output: var abVar = this.method; var a = abVar[0]; var b = abVar[1];
if (declaration?.name.kind === ts.SyntaxKind.ArrayBindingPattern) {
Expand Down
2 changes: 2 additions & 0 deletions src/phpTranspiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export class PhpTranspiler extends BaseTranspiler {
this.id = "php";
this.asyncTranspiling = config['async'] ?? true;
this.uncamelcaseIdentifiers = config['uncamelcaseIdentifiers'] ?? false;
this.removeVariableDeclarationForFunctionExpression = config['removeFunctionAssignToVariable'] ?? false;
this.includeFunctionNameInFunctionExpressionDeclaration = config['includeFunctionNameInFunctionExpressionDeclaration'] ?? false;

this.propRequiresScopeResolutionOperator = ['super'] + (config['ScopeResolutionProps'] ?? []);

Expand Down
2 changes: 2 additions & 0 deletions src/pythonTranspiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export class PythonTranspiler extends BaseTranspiler {
this.initConfig();
this.asyncTranspiling = config['async'] ?? true;
this.uncamelcaseIdentifiers = config['uncamelcaseIdentifiers'] ?? true;
this.removeVariableDeclarationForFunctionExpression = config['removeVariableDeclarationForFunctionExpression'] ?? true;
this.includeFunctionNameInFunctionExpressionDeclaration = config['includeFunctionNameInFunctionExpressionDeclaration'] ?? true;

// user overrides
this.applyUserOverrides(config);
Expand Down
13 changes: 13 additions & 0 deletions tests/csharpTranspiler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,19 @@ describe('csharp transpiling tests', () => {
const output = transpiler.transpileCSharp(ts).content;
expect(output).toBe(cs);
});
test('function expression transpilation', () => {
const ts =
"const consumer = function consumer(a) {\n" +
" return;\n" +
"};";
const csharp =
"void consumer(object a)\n" +
"{\n" +
" return;\n" +
"};";
const output = transpiler.transpileCSharp(ts).content;
expect(output).toBe(csharp);
});
test('basic class with constructor', () => {
const ts =
"class teste extends Test {\n" +
Expand Down
24 changes: 24 additions & 0 deletions tests/phpTranspiler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,30 @@ describe('php transpiling tests', () => {
const output = transpiler.transpilePhp(ts).content;
expect(output).toBe(php);
});
test('function expression transpilation', () => {
const ts =
"const consumer = function consumer (a) {\n" +
" return a;\n" +
"};";
const php =
"$consumer = function ($a) {\n" +
" return $a;\n" +
"};"
const output = transpiler.transpilePhp(ts).content;
expect(output).toBe(php);
});
test('arrow function', () => {
const ts =
"const consumer = (a) => {\n" +
" return a;\n" +
"};";
const php =
"$consumer = function ($a) {\n" +
" return $a;\n" +
"};"
const output = transpiler.transpilePhp(ts).content;
expect(output).toBe(php);
});
test('basic identation check [nested if]', () => {
const ts =
"if (1) {\n" +
Expand Down
11 changes: 11 additions & 0 deletions tests/pythonTranspiler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,17 @@ describe('python tests', () => {
const output = transpiler.transpilePython(ts).content;
expect(output).toBe(py);
});
test('function expression transpilation', () => {
const ts =
"const consumer = function consumer(a) {\n" +
" return a + 1;\n" +
"};\n";
const python =
"def consumer(a):\n" +
" return a + 1";
const output = transpiler.transpilePython(ts).content;
expect(output).toBe(python);
});
test('basic identation test [nested if]', () => {
const ts =
"if (1) {\n" +
Expand Down

0 comments on commit a917edc

Please sign in to comment.