Fix crash on bad namespace parse (#37626)

* Fix crash on bad namespace parse

`global` inside a class body is parsed as a module declaration, and in
the following example has no body:

```ts
class C {
  global x
}
```

`x` is parsed as a separate ExpressionStatement. This caused a crash in
emit because the code didn't expect a module declaration with no body.

* inline node.body variable

* fix missed references to body
This commit is contained in:
Nathan Shively-Sanders
2020-04-01 15:05:49 -07:00
committed by GitHub
parent ed1863b3e6
commit 95a124f802
6 changed files with 87 additions and 19 deletions

View File

@@ -2693,27 +2693,28 @@ namespace ts {
const statements: Statement[] = [];
startLexicalEnvironment();
let statementsLocation: TextRange;
let statementsLocation: TextRange | undefined;
let blockLocation: TextRange | undefined;
const body = node.body!;
if (body.kind === SyntaxKind.ModuleBlock) {
saveStateAndInvoke(body, body => addRange(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement)));
statementsLocation = body.statements;
blockLocation = body;
}
else {
const result = visitModuleDeclaration(<ModuleDeclaration>body);
if (result) {
if (isArray(result)) {
addRange(statements, result);
}
else {
statements.push(result);
}
if (node.body) {
if (node.body.kind === SyntaxKind.ModuleBlock) {
saveStateAndInvoke(node.body, body => addRange(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement)));
statementsLocation = node.body.statements;
blockLocation = node.body;
}
else {
const result = visitModuleDeclaration(<ModuleDeclaration>node.body);
if (result) {
if (isArray(result)) {
addRange(statements, result);
}
else {
statements.push(result);
}
}
const moduleBlock = <ModuleBlock>getInnerMostModuleDeclarationFromDottedModule(node)!.body;
statementsLocation = moveRangePos(moduleBlock.statements, -1);
const moduleBlock = <ModuleBlock>getInnerMostModuleDeclarationFromDottedModule(node)!.body;
statementsLocation = moveRangePos(moduleBlock.statements, -1);
}
}
insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
@@ -2750,7 +2751,7 @@ namespace ts {
// })(hi = hello.hi || (hello.hi = {}));
// })(hello || (hello = {}));
// We only want to emit comment on the namespace which contains block body itself, not the containing namespaces.
if (body.kind !== SyntaxKind.ModuleBlock) {
if (!node.body || node.body.kind !== SyntaxKind.ModuleBlock) {
setEmitFlags(block, getEmitFlags(block) | EmitFlags.NoComments);
}
return block;