Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions internal/printer/emitcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,19 @@ func (c *EmitContext) AddInitializationStatement(node *ast.Node) {
scope.initializationStatements = append(scope.initializationStatements, node)
}

func (c *EmitContext) ConvertToFunctionBlock(node *ast.Node, multiLine bool) *ast.Node {
if ast.IsBlock(node) {
return node
}
returnStatement := c.Factory.NewReturnStatement(node)
returnStatement.Loc = node.Loc
statements := c.Factory.NewNodeList([]*ast.Node{returnStatement})
statements.Loc = node.Loc
block := c.Factory.NewBlock(statements, multiLine)
block.Loc = node.Loc
return block
}

func (c *EmitContext) VisitFunctionBody(node *ast.BlockOrExpression, visitor *ast.NodeVisitor) *ast.BlockOrExpression {
// !!! c.resumeVariableEnvironment()
updated := visitor.VisitNode(node)
Expand All @@ -913,8 +926,13 @@ func (c *EmitContext) VisitFunctionBody(node *ast.BlockOrExpression, visitor *as
}

if !ast.IsBlock(updated) {
statements := c.MergeEnvironment([]*ast.Statement{c.Factory.NewReturnStatement(updated)}, declarations)
return c.Factory.NewBlock(c.Factory.NewNodeList(statements), false /*multiLine*/)
c.AddEmitFlags(updated, EFNoComments)
block := c.ConvertToFunctionBlock(updated, false /*multiLine*/)
return c.Factory.UpdateBlock(
block.AsBlock(),
c.MergeEnvironmentList(block.StatementList(), declarations),
block.AsBlock().MultiLine,
)
}

return c.Factory.UpdateBlock(
Expand Down
19 changes: 4 additions & 15 deletions internal/transformers/estransforms/async.go
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,10 @@ func (tx *asyncTransformer) transformAsyncFunctionBody(node *ast.Node, outerPara
)

if captureLexicalArguments && tx.lexicalArguments.used {
block := tx.convertToFunctionBlock(result)
block := tx.EmitContext().ConvertToFunctionBlock(result, true /*multiLine*/)
if !ast.IsBlock(result) {
tx.EmitContext().SetOriginal(block.StatementList().Nodes[0], result)
}
result = tx.Factory().UpdateBlock(
block.AsBlock(),
tx.EmitContext().MergeEnvironmentList(block.StatementList(), []*ast.Node{tx.createCaptureArgumentsStatement()}),
Expand Down Expand Up @@ -889,20 +892,6 @@ func (tx *asyncTransformer) transformAsyncFunctionBodyWorker(body *ast.Node) *as
return block
}

func (tx *asyncTransformer) convertToFunctionBlock(node *ast.Node) *ast.Node {
if ast.IsBlock(node) {
return node
}
ret := tx.Factory().NewReturnStatement(node)
ret.Loc = node.Loc
tx.EmitContext().SetOriginal(ret, node)
list := tx.Factory().NewNodeList([]*ast.Node{ret})
list.Loc = node.Loc
block := tx.Factory().NewBlock(list, true)
block.Loc = node.Loc
return block
}

// assignmentTargetContainsSuperProperty checks top-down whether an assignment target
// expression contains a super property or element access (super.x or super[x]).
// This avoids relying on parent pointers (IsAssignmentTarget) which may not be set
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//// [tests/cases/compiler/optionalChainingArrowFunctionCommentEs2018.ts] ////

//// [optionalChainingArrowFunctionCommentEs2018.ts]
const thing = { nested: { condition: true } };

const wat = () =>
// explanatory comment
thing?.nested?.condition ? "pass" : "fail";

const watInline = () => /* inline explanatory comment */ thing?.nested?.condition ? "pass" : "fail";

const watInlineMultiline = () => /* inline
explanatory comment */ thing?.nested?.condition ? "pass" : "fail";

const watInlineThenLeading = () => /* inline explanatory comment */
// leading explanatory comment
thing?.nested?.condition ? "pass" : "fail";

declare const o: { a?: number[] };

export const f = () =>
// comment
o.a?.length;


//// [optionalChainingArrowFunctionCommentEs2018.js]
const thing = { nested: { condition: true } };
const wat = () => { var _a;
// explanatory comment
return ((_a = thing === null || thing === void 0 ? void 0 : thing.nested) === null || _a === void 0 ? void 0 : _a.condition) ? "pass" : "fail"; };
const watInline = () => /* inline explanatory comment */ { var _a; /* inline explanatory comment */ return ((_a = thing === null || thing === void 0 ? void 0 : thing.nested) === null || _a === void 0 ? void 0 : _a.condition) ? "pass" : "fail"; };
const watInlineMultiline = () => /* inline
explanatory comment */ { var _a; /* inline
explanatory comment */ return ((_a = thing === null || thing === void 0 ? void 0 : thing.nested) === null || _a === void 0 ? void 0 : _a.condition) ? "pass" : "fail"; };
const watInlineThenLeading = () => /* inline explanatory comment */ { var _a; /* inline explanatory comment */
// leading explanatory comment
return ((_a = thing === null || thing === void 0 ? void 0 : thing.nested) === null || _a === void 0 ? void 0 : _a.condition) ? "pass" : "fail"; };
export const f = () => { var _a;
// comment
return (_a = o.a) === null || _a === void 0 ? void 0 : _a.length; };
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//// [tests/cases/compiler/optionalChainingArrowFunctionCommentEs2018.ts] ////

=== optionalChainingArrowFunctionCommentEs2018.ts ===
const thing = { nested: { condition: true } };
>thing : Symbol(thing, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 5))
>nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))

const wat = () =>
>wat : Symbol(wat, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 2, 5))

// explanatory comment
thing?.nested?.condition ? "pass" : "fail";
>thing?.nested?.condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))
>thing?.nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>thing : Symbol(thing, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 5))
>nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))

const watInline = () => /* inline explanatory comment */ thing?.nested?.condition ? "pass" : "fail";
>watInline : Symbol(watInline, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 6, 5))
>thing?.nested?.condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))
>thing?.nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>thing : Symbol(thing, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 5))
>nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))

const watInlineMultiline = () => /* inline
>watInlineMultiline : Symbol(watInlineMultiline, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 8, 5))

explanatory comment */ thing?.nested?.condition ? "pass" : "fail";
>thing?.nested?.condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))
>thing?.nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>thing : Symbol(thing, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 5))
>nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))

const watInlineThenLeading = () => /* inline explanatory comment */
>watInlineThenLeading : Symbol(watInlineThenLeading, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 11, 5))

// leading explanatory comment
thing?.nested?.condition ? "pass" : "fail";
>thing?.nested?.condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))
>thing?.nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>thing : Symbol(thing, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 5))
>nested : Symbol(nested, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 15))
>condition : Symbol(condition, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 0, 25))

declare const o: { a?: number[] };
>o : Symbol(o, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 15, 13))
>a : Symbol(a, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 15, 18))

export const f = () =>
>f : Symbol(f, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 17, 12))

// comment
o.a?.length;
>o.a?.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>o.a : Symbol(a, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 15, 18))
>o : Symbol(o, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 15, 13))
>a : Symbol(a, Decl(optionalChainingArrowFunctionCommentEs2018.ts, 15, 18))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))

Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//// [tests/cases/compiler/optionalChainingArrowFunctionCommentEs2018.ts] ////

=== optionalChainingArrowFunctionCommentEs2018.ts ===
const thing = { nested: { condition: true } };
>thing : { nested: { condition: boolean; }; }
>{ nested: { condition: true } } : { nested: { condition: boolean; }; }
>nested : { condition: boolean; }
>{ condition: true } : { condition: boolean; }
>condition : boolean
>true : true

const wat = () =>
>wat : () => "fail" | "pass"
>() => // explanatory comment thing?.nested?.condition ? "pass" : "fail" : () => "fail" | "pass"

// explanatory comment
thing?.nested?.condition ? "pass" : "fail";
>thing?.nested?.condition ? "pass" : "fail" : "fail" | "pass"
>thing?.nested?.condition : boolean
>thing?.nested : { condition: boolean; }
>thing : { nested: { condition: boolean; }; }
>nested : { condition: boolean; }
>condition : boolean
>"pass" : "pass"
>"fail" : "fail"

const watInline = () => /* inline explanatory comment */ thing?.nested?.condition ? "pass" : "fail";
>watInline : () => "fail" | "pass"
>() => /* inline explanatory comment */ thing?.nested?.condition ? "pass" : "fail" : () => "fail" | "pass"
>thing?.nested?.condition ? "pass" : "fail" : "fail" | "pass"
>thing?.nested?.condition : boolean
>thing?.nested : { condition: boolean; }
>thing : { nested: { condition: boolean; }; }
>nested : { condition: boolean; }
>condition : boolean
>"pass" : "pass"
>"fail" : "fail"

const watInlineMultiline = () => /* inline
>watInlineMultiline : () => "fail" | "pass"
>() => /* inlineexplanatory comment */ thing?.nested?.condition ? "pass" : "fail" : () => "fail" | "pass"

explanatory comment */ thing?.nested?.condition ? "pass" : "fail";
>thing?.nested?.condition ? "pass" : "fail" : "fail" | "pass"
>thing?.nested?.condition : boolean
>thing?.nested : { condition: boolean; }
>thing : { nested: { condition: boolean; }; }
>nested : { condition: boolean; }
>condition : boolean
>"pass" : "pass"
>"fail" : "fail"

const watInlineThenLeading = () => /* inline explanatory comment */
>watInlineThenLeading : () => "fail" | "pass"
>() => /* inline explanatory comment */ // leading explanatory comment thing?.nested?.condition ? "pass" : "fail" : () => "fail" | "pass"

// leading explanatory comment
thing?.nested?.condition ? "pass" : "fail";
>thing?.nested?.condition ? "pass" : "fail" : "fail" | "pass"
>thing?.nested?.condition : boolean
>thing?.nested : { condition: boolean; }
>thing : { nested: { condition: boolean; }; }
>nested : { condition: boolean; }
>condition : boolean
>"pass" : "pass"
>"fail" : "fail"

declare const o: { a?: number[] };
>o : { a?: number[]; }
>a : number[] | undefined

export const f = () =>
>f : () => number | undefined
>() => // comment o.a?.length : () => number | undefined

// comment
o.a?.length;
>o.a?.length : number | undefined
>o.a : number[] | undefined
>o : { a?: number[]; }
>a : number[] | undefined
>length : number | undefined

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @target: es2018

const thing = { nested: { condition: true } };

const wat = () =>
// explanatory comment
thing?.nested?.condition ? "pass" : "fail";

const watInline = () => /* inline explanatory comment */ thing?.nested?.condition ? "pass" : "fail";

const watInlineMultiline = () => /* inline
explanatory comment */ thing?.nested?.condition ? "pass" : "fail";

const watInlineThenLeading = () => /* inline explanatory comment */
// leading explanatory comment
thing?.nested?.condition ? "pass" : "fail";

declare const o: { a?: number[] };

export const f = () =>
// comment
o.a?.length;