From 7218a71027921b24c396fcb4bcc69271eb14c3dd Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 18 Sep 2017 08:10:07 -0700 Subject: [PATCH] Ensure that emitter calls callbacks for empty blocks --- src/compiler/emitter.ts | 51 ++++++------------- .../convertToEs6Class_emptyCatchClause.ts | 20 ++++++++ .../extract-method-empty-namespace.ts | 22 ++++++++ 3 files changed, 57 insertions(+), 36 deletions(-) create mode 100644 tests/cases/fourslash/convertToEs6Class_emptyCatchClause.ts create mode 100644 tests/cases/fourslash/extract-method-empty-namespace.ts diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 2c6eef3672f79..502329bbd8422 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1440,29 +1440,18 @@ namespace ts { // function emitBlock(node: Block) { - if (isSingleLineEmptyBlock(node)) { - writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node); - write(" "); - writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node); - } - else { - writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node); - emitBlockStatements(node); - // We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted - increaseIndent(); - emitLeadingCommentsOfPosition(node.statements.end); - decreaseIndent(); - writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node); - } + writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node); + emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node)); + // We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted + increaseIndent(); + emitLeadingCommentsOfPosition(node.statements.end); + decreaseIndent(); + writeToken(SyntaxKind.CloseBraceToken, node.statements.end, /*contextNode*/ node); } - function emitBlockStatements(node: BlockLike) { - if (getEmitFlags(node) & EmitFlags.SingleLine) { - emitList(node, node.statements, ListFormat.SingleLineBlockStatements); - } - else { - emitList(node, node.statements, ListFormat.MultiLineBlockStatements); - } + function emitBlockStatements(node: BlockLike, forceSingleLine: boolean) { + const format = forceSingleLine || getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineBlockStatements : ListFormat.MultiLineBlockStatements; + emitList(node, node.statements, format); } function emitVariableStatement(node: VariableStatement) { @@ -1889,16 +1878,11 @@ namespace ts { } function emitModuleBlock(node: ModuleBlock) { - if (isEmptyBlock(node)) { - write("{ }"); - } - else { - pushNameGenerationScope(); - write("{"); - emitBlockStatements(node); - write("}"); - popNameGenerationScope(); - } + pushNameGenerationScope(); + write("{"); + emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node)); + write("}"); + popNameGenerationScope(); } function emitCaseBlock(node: CaseBlock) { @@ -2762,11 +2746,6 @@ namespace ts { && !rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile); } - function isSingleLineEmptyBlock(block: Block) { - return !block.multiLine - && isEmptyBlock(block); - } - function isEmptyBlock(block: BlockLike) { return block.statements.length === 0 && rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile); diff --git a/tests/cases/fourslash/convertToEs6Class_emptyCatchClause.ts b/tests/cases/fourslash/convertToEs6Class_emptyCatchClause.ts new file mode 100644 index 0000000000000..e9027178aa71b --- /dev/null +++ b/tests/cases/fourslash/convertToEs6Class_emptyCatchClause.ts @@ -0,0 +1,20 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: /a.js +////function /**/MyClass() {} +////MyClass.prototype.foo = function() { +//// try {} catch() {} +////} + +verify.applicableRefactorAvailableAtMarker(""); +verify.fileAfterApplyingRefactorAtMarker("", +`class MyClass { + constructor() { } + foo() { + try { } + catch () { } + } +} +`, +'Convert to ES2015 class', 'convert'); diff --git a/tests/cases/fourslash/extract-method-empty-namespace.ts b/tests/cases/fourslash/extract-method-empty-namespace.ts new file mode 100644 index 0000000000000..9da3faaf92704 --- /dev/null +++ b/tests/cases/fourslash/extract-method-empty-namespace.ts @@ -0,0 +1,22 @@ +/// + +// TODO: GH#18546 +// For now this tests that at least we don't crash. + +////function f() { +//// /*start*/namespace N {}/*end*/ +////} + +goTo.select('start', 'end') +edit.applyRefactor({ + refactorName: "Extract Method", + actionName: "scope_1", + actionDescription: "Extract to function in global scope", + newContent: `function f() { + /*RENAME*/newFunction(N); +} +function newFunction(N: any) { + namespace N { } +} +` +});