Browse Source

preserve effects in for-of loop (#870)

gh-953
Rich-Harris 8 years ago
parent
commit
b82375c273
  1. 15
      src/ast/nodes/ForInStatement.js
  2. 15
      src/ast/nodes/ForOfStatement.js
  3. 4
      src/ast/nodes/index.js
  4. 3
      test/form/effect-in-for-of-loop/_config.js
  5. 19
      test/form/effect-in-for-of-loop/_expected/amd.js
  6. 17
      test/form/effect-in-for-of-loop/_expected/cjs.js
  7. 15
      test/form/effect-in-for-of-loop/_expected/es.js
  8. 20
      test/form/effect-in-for-of-loop/_expected/iife.js
  9. 23
      test/form/effect-in-for-of-loop/_expected/umd.js
  10. 23
      test/form/effect-in-for-of-loop/main.js

15
src/ast/nodes/ForInStatement.js

@ -0,0 +1,15 @@
import Node from '../Node.js';
import { STRING } from '../values.js';
export default class ForInStatement extends Node {
initialise ( scope ) {
super.initialise( scope );
// special case
if ( this.left.type === 'VariableDeclaration' ) {
for ( const proxy of this.left.declarations[0].proxies.values() ) {
proxy.possibleValues.add( STRING );
}
}
}
}

15
src/ast/nodes/ForOfStatement.js

@ -0,0 +1,15 @@
import Node from '../Node.js';
import { UNKNOWN } from '../values.js';
export default class ForOfStatement extends Node {
initialise ( scope ) {
super.initialise( scope );
// special case
if ( this.left.type === 'VariableDeclaration' ) {
for ( const proxy of this.left.declarations[0].proxies.values() ) {
proxy.possibleValues.add( UNKNOWN );
}
}
}
}

4
src/ast/nodes/index.js

@ -11,6 +11,8 @@ import ExportAllDeclaration from './ExportAllDeclaration.js';
import ExportDefaultDeclaration from './ExportDefaultDeclaration.js';
import ExportNamedDeclaration from './ExportNamedDeclaration.js';
import ExpressionStatement from './ExpressionStatement.js';
import ForInStatement from './ForInStatement.js';
import ForOfStatement from './ForOfStatement.js';
import FunctionDeclaration from './FunctionDeclaration.js';
import FunctionExpression from './FunctionExpression.js';
import Identifier from './Identifier.js';
@ -43,6 +45,8 @@ export default {
ExportDefaultDeclaration,
ExportNamedDeclaration,
ExpressionStatement,
ForInStatement,
ForOfStatement,
FunctionDeclaration,
FunctionExpression,
Identifier,

3
test/form/effect-in-for-of-loop/_config.js

@ -0,0 +1,3 @@
module.exports = {
description: 'includes effects in for-of loop (#870)'
}

19
test/form/effect-in-for-of-loop/_expected/amd.js

@ -0,0 +1,19 @@
define(function () { 'use strict';
const items = [{}, {}, {}];
function x () {
for ( const item of items.children ) {
item.foo = 'bar';
}
}
x();
assert.deepEqual( items, [
{ foo: 'bar' },
{ foo: 'bar' },
{ foo: 'bar' }
]);
});

17
test/form/effect-in-for-of-loop/_expected/cjs.js

@ -0,0 +1,17 @@
'use strict';
const items = [{}, {}, {}];
function x () {
for ( const item of items.children ) {
item.foo = 'bar';
}
}
x();
assert.deepEqual( items, [
{ foo: 'bar' },
{ foo: 'bar' },
{ foo: 'bar' }
]);

15
test/form/effect-in-for-of-loop/_expected/es.js

@ -0,0 +1,15 @@
const items = [{}, {}, {}];
function x () {
for ( const item of items.children ) {
item.foo = 'bar';
}
}
x();
assert.deepEqual( items, [
{ foo: 'bar' },
{ foo: 'bar' },
{ foo: 'bar' }
]);

20
test/form/effect-in-for-of-loop/_expected/iife.js

@ -0,0 +1,20 @@
(function () {
'use strict';
const items = [{}, {}, {}];
function x () {
for ( const item of items.children ) {
item.foo = 'bar';
}
}
x();
assert.deepEqual( items, [
{ foo: 'bar' },
{ foo: 'bar' },
{ foo: 'bar' }
]);
}());

23
test/form/effect-in-for-of-loop/_expected/umd.js

@ -0,0 +1,23 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
typeof define === 'function' && define.amd ? define(factory) :
(factory());
}(this, (function () { 'use strict';
const items = [{}, {}, {}];
function x () {
for ( const item of items.children ) {
item.foo = 'bar';
}
}
x();
assert.deepEqual( items, [
{ foo: 'bar' },
{ foo: 'bar' },
{ foo: 'bar' }
]);
})));

23
test/form/effect-in-for-of-loop/main.js

@ -0,0 +1,23 @@
const items = [{}, {}, {}];
function x () {
for ( const item of items.children ) {
item.foo = 'bar';
}
}
x();
function y () {
for ( const item of items.children ) {
// do nothing
}
}
y();
assert.deepEqual( items, [
{ foo: 'bar' },
{ foo: 'bar' },
{ foo: 'bar' }
]);
Loading…
Cancel
Save