From aa73942520fe122bc846a4894972e4d81ee3d40f Mon Sep 17 00:00:00 2001 From: meixg Date: Wed, 6 Nov 2019 20:22:46 +0800 Subject: [PATCH] fix: #75 --- src/emitter.ts | 61 +++++++++++++++-------- src/utilities/nodeTest.ts | 2 +- test/features/Class.php | 2 +- test/features/ObjectLiteralExpression.php | 8 ++- test/features/ObjectLiteralExpression.ts | 9 +++- test/features/import.php | 6 +-- test/features/inheritedVariables.php | 2 +- test/index.js | 3 ++ typescript.d.ts | 1 + 9 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/emitter.ts b/src/emitter.ts index 222412b..7c4622a 100644 --- a/src/emitter.ts +++ b/src/emitter.ts @@ -1227,25 +1227,7 @@ export function emitFile( writeBase("$"); } - let writeNamespace = false; - if (ts.isIdentifier(node.expression)) { - const symbol = typeChecker.getSymbolAtLocation(node.expression); - - if (symbol) { - const declarations = symbol.getDeclarations(); - - if (declarations.length && ts.isImportSpecifier(declarations[0])) { - const specifier = declarations[0] as ts.ImportSpecifier; - const declaration = specifier.parent.parent.parent as ts.ImportDeclaration; - const moduleName = declaration.moduleSpecifier.getText().replace(/^['"]/, '').replace(/['"]$/, ''); - const namespace = state.modules[moduleName] && state.modules[moduleName].namespace; - namespace && writeBase(namespace); - writeNamespace = true; - emitExpression(specifier.propertyName || specifier.name) - } - } - - } + let writeNamespace = emitIdentifierFromImport(node.expression); if (!writeNamespace) { emitWithHint(ts.EmitHint.Expression, node.expression); } @@ -2378,7 +2360,17 @@ export function emitFile( writeSpace(); writePunctuation("=>"); writeSpace(); - emitExpression(node.initializer); + if (isFunctionLike(node.initializer, typeChecker) && !isVariable(node.initializer, typeChecker) && !ts.isFunctionLikeDeclaration(node.initializer)) { + writeBase('"'); + let fromImport = emitIdentifierFromImport(node.initializer); + if (!fromImport) { + emit(node.initializer); + } + writeBase('"'); + } + else { + emitExpression(node.initializer); + } } function emitShorthandPropertyAssignment(node: ts.ShorthandPropertyAssignment) { @@ -2398,7 +2390,8 @@ export function emitFile( if (isFunctionLike(node, typeChecker) && !isVariable(node, typeChecker)) { writeBase('"'); - emit(node.name); + let fromImport = emitIdentifierFromImport(node.name); + !fromImport && emit(node.name); writeBase('"'); } else { @@ -3019,6 +3012,32 @@ export function emitFile( } } + + /** + * identifier from import may need add namespace + */ + function emitIdentifierFromImport(node: ts.Node): boolean { + if (ts.isIdentifier(node)) { + const type = typeChecker.getTypeAtLocation(node); + const symbol = typeChecker.getSymbolAtLocation(node); + + if (symbol) { + const declarations = symbol.getDeclarations(); + + if (declarations.length && ts.isImportSpecifier(declarations[0])) { + const specifier = declarations[0] as ts.ImportSpecifier; + const declaration = specifier.parent.parent.parent as ts.ImportDeclaration; + const moduleName = declaration.moduleSpecifier.getText().replace(/^['"]/, '').replace(/['"]$/, ''); + const namespace = state.modules[moduleName] && state.modules[moduleName].namespace; + namespace && writeBase(namespace); + emitExpression(specifier.propertyName || specifier.name); + return true; + } + } + + } + } + // function commitPendingSemicolonInternal() { // if (pendingSemicolon) { // writeSemicolonInternal(); diff --git a/src/utilities/nodeTest.ts b/src/utilities/nodeTest.ts index 9ee2802..8d28a32 100644 --- a/src/utilities/nodeTest.ts +++ b/src/utilities/nodeTest.ts @@ -46,7 +46,7 @@ export function shouldAddDollar(node: Node, state: CompilerState): boolean { return false; } - if (isFunctionLike(node, state.typeChecker) && node.parent && ts.isImportSpecifier(node.parent)) { + if (isFunctionLike(node, state.typeChecker) && !isVariable(node, state.typeChecker)) { return false; } diff --git a/test/features/Class.php b/test/features/Class.php index 2ebe988..54f4fbd 100644 --- a/test/features/Class.php +++ b/test/features/Class.php @@ -1,7 +1,7 @@ 123, "b" => "456" @@ -37,7 +38,12 @@ function aaa() { echo "ccc"; }, "ddd" => $ddd, - "eee" => $eee + "eee" => $eee, + "fff" => "aaa", + "ggg" => $bbb, + "hhh" => $ddd, + "iii" => $eee, + "jjj" => "\someModule\func" ); $mmm["aaa"](); $mmm["bbb"](); diff --git a/test/features/ObjectLiteralExpression.ts b/test/features/ObjectLiteralExpression.ts index bdf5a10..fc81aad 100644 --- a/test/features/ObjectLiteralExpression.ts +++ b/test/features/ObjectLiteralExpression.ts @@ -1,3 +1,5 @@ +import {func as func1} from '../some-utils'; + const b = { a: 123, b: '456' @@ -44,7 +46,12 @@ let mmm = { console.log('ccc'); }, ddd, - eee + eee, + fff: aaa, + ggg: bbb, + hhh: ddd, + iii: eee, + jjj: func1 }; mmm.aaa(); diff --git a/test/features/import.php b/test/features/import.php index 1b62393..bbe90f7 100644 --- a/test/features/import.php +++ b/test/features/import.php @@ -1,13 +1,13 @@ "hello" ); diff --git a/test/features/inheritedVariables.php b/test/features/inheritedVariables.php index af63873..8411874 100644 --- a/test/features/inheritedVariables.php +++ b/test/features/inheritedVariables.php @@ -1,7 +1,7 @@ "123456" ); diff --git a/test/index.js b/test/index.js index 80e7dbf..c2f17da 100644 --- a/test/index.js +++ b/test/index.js @@ -41,6 +41,9 @@ describe('features', () => { 'vue': { required: true } + }, + getModuleNamespace(name) { + return '\\someModule\\'; } }); assert.equal(res.phpCode, phpContent); diff --git a/typescript.d.ts b/typescript.d.ts index 2204537..6ed32bb 100644 --- a/typescript.d.ts +++ b/typescript.d.ts @@ -4040,6 +4040,7 @@ declare namespace ts { function isPropertyName(node: Node): node is PropertyName; function isBindingName(node: Node): node is BindingName; function isFunctionLike(node: Node): node is SignatureDeclaration; + function isFunctionLikeDeclaration(node: Node): node is FunctionLikeDeclaration; function isClassElement(node: Node): node is ClassElement; function isClassLike(node: Node): node is ClassLikeDeclaration; function isAccessor(node: Node): node is AccessorDeclaration;