From cac12526d8a5e133adb871f33234adea5f8c33cd Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Mon, 12 Sep 2022 23:26:55 -0700 Subject: [PATCH] use safer and more reliable approach to cast Directive to ExpressionStatement --- packages/babel-parser/src/plugins/estree.ts | 43 +++--------- .../directives/interleaved-comments/input.js | 4 ++ .../interleaved-comments/output.json | 67 +++++++++++++++++++ 3 files changed, 82 insertions(+), 32 deletions(-) create mode 100644 packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/input.js create mode 100644 packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/output.json diff --git a/packages/babel-parser/src/plugins/estree.ts b/packages/babel-parser/src/plugins/estree.ts index e97af9aabbca..60e7b4871552 100644 --- a/packages/babel-parser/src/plugins/estree.ts +++ b/packages/babel-parser/src/plugins/estree.ts @@ -95,38 +95,20 @@ export default (superClass: typeof Parser) => return this.estreeParseLiteral(value); } + // Cast a Directive to an ExpressionStatement. Mutates the input Directive. directiveToStmt(directive: N.Directive): N.ExpressionStatement { - const directiveLiteral = directive.value; + const stmt = directive as any; + stmt.type = "ExpressionStatement"; + stmt.directive = stmt.value.extra.rawValue; + stmt.expression = stmt.value; + delete stmt.value; - const stmt = this.startNodeAt( - directive.start, - directive.loc.start, - ); - const expression = this.startNodeAt( - directiveLiteral.start, - directiveLiteral.loc.start, - ); - - expression.value = directiveLiteral.extra.expressionValue; - // @ts-expect-error TS2339: Property 'raw' does not exist on type 'Undone '. - expression.raw = directiveLiteral.extra.raw; - - stmt.leadingComments = directive.leadingComments?.slice(); - stmt.trailingComments = directive.trailingComments?.slice(); + stmt.expression.type = "Literal"; + stmt.expression.raw = stmt.expression.extra.raw; + stmt.expression.value = stmt.expression.extra.expressionValue; + delete stmt.expression.extra; - stmt.expression = this.finishNodeAt( - expression, - "Literal", - directiveLiteral.loc.end, - ); - // @ts-expect-error N.Directive.value is not defined - stmt.directive = directiveLiteral.extra.raw.slice(1, -1); - - return this.finishNodeAt( - stmt, - "ExpressionStatement", - directive.loc.end, - ) as N.ExpressionStatement; + return stmt as N.ExpressionStatement; } // ================================== @@ -178,9 +160,6 @@ export default (superClass: typeof Parser) => end, afterBlockParse, ); - if (node.directives.length) { - this.processComment(node); - } const directiveStatements = node.directives.map(d => this.directiveToStmt(d), diff --git a/packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/input.js b/packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/input.js new file mode 100644 index 000000000000..24c853e6bc11 --- /dev/null +++ b/packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/input.js @@ -0,0 +1,4 @@ +// 1; +"use strict"; +// 2; +"use strict"; diff --git a/packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/output.json b/packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/output.json new file mode 100644 index 000000000000..b71ae9db581d --- /dev/null +++ b/packages/babel-parser/test/fixtures/estree/directives/interleaved-comments/output.json @@ -0,0 +1,67 @@ +{ + "type": "File", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":13}}, + "program": { + "type": "Program", + "start":0,"end":39,"loc":{"start":{"line":1,"column":0},"end":{"line":4,"column":13}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":6,"end":19,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":13}}, + "trailingComments": [ + { + "type": "CommentLine", + "value": " 2;", + "start":20,"end":25,"loc":{"start":{"line":3,"column":0,"index":20},"end":{"line":3,"column":5,"index":25}} + } + ], + "leadingComments": [ + { + "type": "CommentLine", + "value": " 1;", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":5,"index":5}} + } + ], + "directive": "use strict", + "expression": { + "type": "Literal", + "start":6,"end":18,"loc":{"start":{"line":2,"column":0},"end":{"line":2,"column":12}}, + "value": "use strict", + "raw": "\"use strict\"" + } + }, + { + "type": "ExpressionStatement", + "start":26,"end":39,"loc":{"start":{"line":4,"column":0},"end":{"line":4,"column":13}}, + "leadingComments": [ + { + "type": "CommentLine", + "value": " 2;", + "start":20,"end":25,"loc":{"start":{"line":3,"column":0,"index":20},"end":{"line":3,"column":5,"index":25}} + } + ], + "directive": "use strict", + "expression": { + "type": "Literal", + "start":26,"end":38,"loc":{"start":{"line":4,"column":0},"end":{"line":4,"column":12}}, + "value": "use strict", + "raw": "\"use strict\"" + } + } + ] + }, + "comments": [ + { + "type": "CommentLine", + "value": " 1;", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":1,"column":5,"index":5}} + }, + { + "type": "CommentLine", + "value": " 2;", + "start":20,"end":25,"loc":{"start":{"line":3,"column":0,"index":20},"end":{"line":3,"column":5,"index":25}} + } + ] +}