From 7ff1b238e2911bf4d3114e4a2e74189aed85d5ab Mon Sep 17 00:00:00 2001 From: cxtom Date: Tue, 7 May 2019 17:50:47 +0800 Subject: [PATCH] feat: rest arguments support --- README.md | 7 ++- src/index.ts | 4 +- src/transformer.ts | 61 ++++++++++++++++--- .../{Spread.php => restArguments.php} | 5 +- test/features/{Spread.ts => restArguments.ts} | 3 + 5 files changed, 68 insertions(+), 12 deletions(-) rename test/features/{Spread.php => restArguments.php} (71%) rename test/features/{Spread.ts => restArguments.ts} (79%) diff --git a/README.md b/README.md index adfda13..578013a 100644 --- a/README.md +++ b/README.md @@ -429,6 +429,8 @@ $f = function () use(&$b) { ```typescript function funcA(...args: string[]) { } +function funcC(a: string, ...args: string[]) { +} ``` output @@ -437,9 +439,12 @@ output function funcA() { $args = func_get_args(); } +function funcC() { + $a = func_get_arg(0); $args = array_slice(func_get_args(), 1); +} ``` -> 注:箭头函数暂不支持,并且只能用于所有参数都用 `...` 来加载的情况 +> 注:箭头函数暂不支持 ### Core JavaScript API diff --git a/src/index.ts b/src/index.ts index 8bbcc6c..cbe4fed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -79,7 +79,6 @@ export function compile(filePath: string, options: Ts2phpOptions = {}) { }; } - project.resolveSourceFileDependencies(); const program = project.getProgram().compilerObject; @@ -145,6 +144,7 @@ export function compile(filePath: string, options: Ts2phpOptions = {}) { return { phpCode: code, - errors: state.errors + errors: state.errors, + sourceFile: state.sourceFile }; } diff --git a/src/transformer.ts b/src/transformer.ts index 877e96a..bcbb48b 100644 --- a/src/transformer.ts +++ b/src/transformer.ts @@ -337,26 +337,71 @@ export function transform(context: ts.TransformationContext) { const parameterIndex = node.parameters.findIndex(node => !!node.dotDotDotToken); - if (parameterIndex > 0) { + if (parameterIndex < 0) { return node.body; } const parameter = node.parameters[parameterIndex]; - const declarationName = parameter.name.kind === ts.SyntaxKind.Identifier ? ts.getMutableClone(parameter.name) : ts.createTempVariable(/*recordTempVariable*/ undefined); - node.parameters = ts.createNodeArray(node.parameters.filter(node => !node.dotDotDotToken)); - const statement = ts.createVariableStatement( - /*modifiers*/ undefined, - ts.createVariableDeclarationList([ + const declarationName = parameter.name.kind === ts.SyntaxKind.Identifier + ? ts.getMutableClone(parameter.name) + : ts.createTempVariable(/*recordTempVariable*/ undefined); + + const parameters = [...node.parameters]; + node.parameters = ts.createNodeArray([]); + + let variableDeclarationList: ts.VariableDeclarationList; + + if (parameterIndex === 0) { + variableDeclarationList = ts.createVariableDeclarationList([ ts.createVariableDeclaration( declarationName, - /*type*/ undefined, + undefined, ts.createCall( ts.createIdentifier('func_get_args'), [], [] ) ) - ]) + ]); + } + else { + let list = parameters + .slice(0, parameters.length - 1) + .map((parameter, index) => + ts.createVariableDeclaration( + parameter.name, + undefined, + ts.createCall( + ts.createIdentifier('func_get_arg'), + [], + [ts.createNumericLiteral(`${index}`)] + ) + ) + ); + list.push( + ts.createVariableDeclaration( + declarationName, + undefined, + ts.createCall( + ts.createIdentifier('array_slice'), + undefined, + [ + ts.createCall( + ts.createIdentifier('func_get_args'), + undefined, + [] + ), + ts.createNumericLiteral(`${parameterIndex}`) + ] + ) + ) + ); + variableDeclarationList = ts.createVariableDeclarationList(list); + } + + const statement = ts.createVariableStatement( + undefined, + variableDeclarationList ); return ts.createBlock( diff --git a/test/features/Spread.php b/test/features/restArguments.php similarity index 71% rename from test/features/Spread.php rename to test/features/restArguments.php index 521070d..18b5af3 100644 --- a/test/features/Spread.php +++ b/test/features/restArguments.php @@ -1,5 +1,5 @@