Skip to content

Commit

Permalink
Merge pull request #707 from rollup/undefined-this
Browse files Browse the repository at this point in the history
rewrite top-level this as undefined
  • Loading branch information
Rich-Harris committed Jun 10, 2016
2 parents f56ed8b + 51c3da9 commit 9d328e0
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 8 deletions.
10 changes: 7 additions & 3 deletions src/Statement.js
Expand Up @@ -41,7 +41,7 @@ export default class Statement {
// find references
const statement = this;
let { module, references, scope, stringLiteralRanges } = this;
let readDepth = 0;
let contextDepth = 0;

walk( this.node, {
enter ( node, parent, prop ) {
Expand All @@ -59,8 +59,12 @@ export default class Statement {
stringLiteralRanges.push([ node.start + 1, node.end - 1 ]);
}

if ( node.type === 'ThisExpression' && contextDepth === 0 ) {
module.magicString.overwrite( node.start, node.end, 'undefined' );
}

if ( node._scope ) scope = node._scope;
if ( /Function/.test( node.type ) ) readDepth += 1;
if ( /^Function/.test( node.type ) ) contextDepth += 1;

let isReassignment;

Expand Down Expand Up @@ -121,7 +125,7 @@ export default class Statement {
},
leave ( node ) {
if ( node._scope ) scope = scope.parent;
if ( /Function/.test( node.type ) ) readDepth -= 1;
if ( /^Function/.test( node.type ) ) contextDepth -= 1;
}
});
}
Expand Down
3 changes: 3 additions & 0 deletions test/form/this-is-undefined/_config.js
@@ -0,0 +1,3 @@
module.exports = {
description: 'top-level `this` expression is rewritten as `undefined`'
};
21 changes: 21 additions & 0 deletions test/form/this-is-undefined/_expected/amd.js
@@ -0,0 +1,21 @@
define(function () { 'use strict';

const fooContext = {};

function foo () {
// inside a function, `this` should be untouched...
assert.strictEqual( this, fooContext );
}

const bar = () => {
// ...unless it's an arrow function
assert.strictEqual( undefined, undefined );
}

foo.call( fooContext );
bar.call( {} );

// outside a function, `this` is undefined
assert.strictEqual( undefined, undefined );

});
19 changes: 19 additions & 0 deletions test/form/this-is-undefined/_expected/cjs.js
@@ -0,0 +1,19 @@
'use strict';

const fooContext = {};

function foo () {
// inside a function, `this` should be untouched...
assert.strictEqual( this, fooContext );
}

const bar = () => {
// ...unless it's an arrow function
assert.strictEqual( undefined, undefined );
}

foo.call( fooContext );
bar.call( {} );

// outside a function, `this` is undefined
assert.strictEqual( undefined, undefined );
17 changes: 17 additions & 0 deletions test/form/this-is-undefined/_expected/es6.js
@@ -0,0 +1,17 @@
const fooContext = {};

function foo () {
// inside a function, `this` should be untouched...
assert.strictEqual( this, fooContext );
}

const bar = () => {
// ...unless it's an arrow function
assert.strictEqual( undefined, undefined );
}

foo.call( fooContext );
bar.call( {} );

// outside a function, `this` is undefined
assert.strictEqual( undefined, undefined );
22 changes: 22 additions & 0 deletions test/form/this-is-undefined/_expected/iife.js
@@ -0,0 +1,22 @@
(function () {
'use strict';

const fooContext = {};

function foo () {
// inside a function, `this` should be untouched...
assert.strictEqual( this, fooContext );
}

const bar = () => {
// ...unless it's an arrow function
assert.strictEqual( undefined, undefined );
}

foo.call( fooContext );
bar.call( {} );

// outside a function, `this` is undefined
assert.strictEqual( undefined, undefined );

}());
25 changes: 25 additions & 0 deletions test/form/this-is-undefined/_expected/umd.js
@@ -0,0 +1,25 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
typeof define === 'function' && define.amd ? define(factory) :
(factory());
}(this, function () { 'use strict';

const fooContext = {};

function foo () {
// inside a function, `this` should be untouched...
assert.strictEqual( this, fooContext );
}

const bar = () => {
// ...unless it's an arrow function
assert.strictEqual( undefined, undefined );
}

foo.call( fooContext );
bar.call( {} );

// outside a function, `this` is undefined
assert.strictEqual( undefined, undefined );

}));
@@ -1,4 +1,4 @@
const fooContext = {}
const fooContext = {};

function foo () {
// inside a function, `this` should be untouched...
Expand Down
4 changes: 0 additions & 4 deletions test/function/this-is-undefined/_config.js

This file was deleted.

0 comments on commit 9d328e0

Please sign in to comment.