Skip to content
Browse files

Fix use strict at file scope, thanks to ideas from @pornel

  • Loading branch information...
1 parent bec0e4b commit f7eb53799e9468c7ba92da95d249c85be34965e8 @gotwarlost committed Dec 16, 2013
Showing with 26 additions and 10 deletions.
  1. +20 −7 lib/instrumenter.js
  2. +6 −3 test/instrumentation/test-strict.js
View
27 lib/instrumenter.js
@@ -386,6 +386,8 @@
* used for embedding the source into the coverage object
*/
instrumentASTSync: function (program, filename, originalCode) {
+ var usingStrict = false,
+ codegenOptions;
filename = filename || String(new Date().getTime()) + '.js';
this.coverState = {
path: filename,
@@ -403,10 +405,16 @@
variable: 0,
statement: 0
};
+ if (program.body && program.body.length > 0 && this.isUseStrictExpression(program.body[0])) {
+ //nuke it
+ program.body.shift();
+ //and add it back at code generation time
+ usingStrict = true;
+ }
this.walker.startWalk(program);
- var codegenOptions = this.opts.codeGenerationOptions || { format: { compact: !this.opts.noCompact }};
+ codegenOptions = this.opts.codeGenerationOptions || { format: { compact: !this.opts.noCompact }};
//console.log(JSON.stringify(program, undefined, 2));
- return this.getPreamble(originalCode || '') + '\n' + ESPGEN.generate(program, codegenOptions) + '\n';
+ return this.getPreamble(originalCode || '', usingStrict) + '\n' + ESPGEN.generate(program, codegenOptions) + '\n';
},
/**
* Callback based instrumentation. Note that this still executes synchronously in the same process tick
@@ -479,11 +487,12 @@
}
},
- getPreamble: function (sourceCode) {
+ getPreamble: function (sourceCode, emitUseStrict) {
var varName = this.opts.coverageVariable || '__coverage__',
file = this.coverState.path.replace(/\\/g, '\\\\'),
tracker = this.currentState.trackerVar,
coverState,
+ strictLine = emitUseStrict ? '"use strict";' : '',
// return replacements using the function to ensure that the replacement is
// treated like a dumb string and not as a string with RE replacement patterns
replacer = function (s) {
@@ -498,12 +507,16 @@
}
coverState = this.opts.debug ? JSON.stringify(this.coverState, undefined, 4) : JSON.stringify(this.coverState);
code = [
- "if (typeof %GLOBAL% === 'undefined') { %GLOBAL% = {}; }",
- "if (!%GLOBAL%['%FILE%']) {",
- " %GLOBAL%['%FILE%'] = %OBJECT%;",
+ "%STRICT%",
+ "var %VAR% = (Function('return this'))();",
+ "if (!%VAR%.%GLOBAL%) { %VAR%.%GLOBAL% = {}; }",
+ "%VAR% = %VAR%.%GLOBAL%;",
+ "if (!(%VAR%['%FILE%'])) {",
+ " %VAR%['%FILE%'] = %OBJECT%;",
"}",
- "var %VAR% = %GLOBAL%['%FILE%'];"
+ "%VAR% = %VAR%['%FILE%'];"
].join("\n")
+ .replace(/%STRICT%/g, replacer(strictLine))
.replace(/%VAR%/g, replacer(tracker))
.replace(/%GLOBAL%/g, replacer(varName))
.replace(/%FILE%/g, replacer(file))
View
9 test/instrumentation/test-strict.js
@@ -103,14 +103,17 @@ module.exports = {
' output = "pass";',
' }'
];
+ console.log(code.join("\n"));
verifier = helper.verifier(__filename, code);
cb();
},
- "should not change behavor (this is a bug!)": function (test) {
+ "should correctly interpret the strict statement": function (test) {
+ // use strict semantics still do not work since it is not top-level but called from vm.runInThisContext
verifier.verify(test, [], "fail", {
- statements: { 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 0 },
- lines: { 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 7: 0 },
+ //however statements and lines should line up
+ statements: { 1: 1, 2: 1, 3: 1, 4: 1, 5: 0 },
+ lines: { 2: 1, 3: 1, 4: 1, 5: 1, 7: 0 },
branches: {},
functions: {}
});

0 comments on commit f7eb537

Please sign in to comment.
Something went wrong with that request. Please try again.