diff --git a/instrument-js.cpp b/instrument-js.cpp index 7a1868a..2814b45 100644 --- a/instrument-js.cpp +++ b/instrument-js.cpp @@ -438,7 +438,7 @@ static void instrument_function(JSParseNode * node, Stream * f, int indent, enum Stream_write_char(f, '}'); } -static void instrument_function_call(JSParseNode * node, Stream * f) { +static void instrument_function_call(JSParseNode * node, Stream * f, bool parenthesize_for_new) { JSParseNode * function_node = node->pn_head; if (function_node->pn_type == TOK_FUNCTION) { JSObject * object = function_node->pn_funpob->object; @@ -455,7 +455,14 @@ static void instrument_function_call(JSParseNode * node, Stream * f) { return; } } + bool parenthesize_callee = parenthesize_for_new && (function_node->pn_type == TOK_LP); // e.g. new (require('foo'))() + if (parenthesize_callee) { + Stream_write_char(f, '('); + } output_expression(function_node, f, false); + if (parenthesize_callee) { + Stream_write_char(f, ')'); + } Stream_write_char(f, '('); for (struct JSParseNode * p = function_node->pn_next; p != NULL; p = p->pn_next) { if (p != node->pn_head->pn_next) { @@ -636,7 +643,7 @@ static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_ break; case TOK_NEW: Stream_write_string(f, "new "); - instrument_function_call(node, f); + instrument_function_call(node, f, true); break; case TOK_DELETE: Stream_write_string(f, "delete "); @@ -693,7 +700,7 @@ static void output_expression(JSParseNode * node, Stream * f, bool parenthesize_ Stream_write_char(f, ']'); break; case TOK_LP: - instrument_function_call(node, f); + instrument_function_call(node, f, false); break; case TOK_RB: Stream_write_char(f, '['); diff --git a/tests/javascript.expected/javascript-new-indirect.js b/tests/javascript.expected/javascript-new-indirect.js new file mode 100644 index 0000000..38c8a4e --- /dev/null +++ b/tests/javascript.expected/javascript-new-indirect.js @@ -0,0 +1,25 @@ +/* automatically generated by JSCoverage - do not edit */ +if (typeof _$jscoverage === 'undefined') _$jscoverage = {}; +if (! _$jscoverage['javascript-new-indirect.js']) { + _$jscoverage['javascript-new-indirect.js'] = []; + _$jscoverage['javascript-new-indirect.js'][1] = 0; + _$jscoverage['javascript-new-indirect.js'][2] = 0; + _$jscoverage['javascript-new-indirect.js'][3] = 0; + _$jscoverage['javascript-new-indirect.js'][4] = 0; + _$jscoverage['javascript-new-indirect.js'][5] = 0; +} +_$jscoverage['javascript-new-indirect.js'][1]++; +function X() { +} +_$jscoverage['javascript-new-indirect.js'][2]++; +function y() { + _$jscoverage['javascript-new-indirect.js'][2]++; + return X; +} +_$jscoverage['javascript-new-indirect.js'][3]++; +x = new (y())(); +_$jscoverage['javascript-new-indirect.js'][4]++; +x = new (y())(1); +_$jscoverage['javascript-new-indirect.js'][5]++; +x = new (y())(1, 2); +_$jscoverage['javascript-new-indirect.js'].source = ["function X() {}","function y() { return X; }","x = new (y())();","x = new (y())(1);","x = new (y())(1, 2);"]; diff --git a/tests/javascript/javascript-new-indirect.js b/tests/javascript/javascript-new-indirect.js new file mode 100644 index 0000000..3fd43c1 --- /dev/null +++ b/tests/javascript/javascript-new-indirect.js @@ -0,0 +1,5 @@ +function X() {} +function y() { return X; } +x = new (y())(); +x = new (y())(1); +x = new (y())(1, 2);