Compare commits

...

14 Commits

Author SHA1 Message Date
Sebastian McKenzie
c129eba712 v3.3.3 2015-02-02 10:52:56 +11:00
Sebastian McKenzie
0e2d7fa941 remove throw expectation on undefiend this tests 2015-02-02 10:50:29 +11:00
Sebastian McKenzie
0b33a62032 fix linting errors 2015-02-02 10:48:18 +11:00
Sebastian McKenzie
6919ed2b34 add 3.3.3 changelog 2015-02-02 10:46:44 +11:00
Sebastian McKenzie
435320e3f9 selfContainify regenerator runtime when building 6to5-runtime - fixes #659 2015-02-02 10:45:26 +11:00
Sebastian McKenzie
7b846af965 3.3.2 2015-02-02 10:45:05 +11:00
Sebastian McKenzie
18b836c16a add allowPartial option to t.buildMatchMemberExpression, fix t.isReferenced on Property nodes - fixes #656 2015-02-02 10:44:56 +11:00
Sebastian McKenzie
fb360039ce remap top level this to undefined - #562 2015-02-02 10:44:17 +11:00
Sebastian McKenzie
4763b95a0d v3.3.2 2015-02-02 01:43:47 +11:00
Sebastian McKenzie
9fe1e37ca7 fix t.buildMatchMemberExpression 2015-02-02 01:41:39 +11:00
Sebastian McKenzie
8a9aac3e68 fix linting errors 2015-02-02 01:37:27 +11:00
Sebastian McKenzie
27138abd29 simplify member expression checking, flesh out react component optimiser #653 2015-02-02 01:30:06 +11:00
Sebastian McKenzie
dcf91db475 add react component optimisation base #653 2015-02-02 00:50:25 +11:00
Sebastian McKenzie
ab63345764 3.3.1 2015-02-01 18:44:46 +11:00
25 changed files with 284 additions and 45 deletions

View File

@@ -11,6 +11,13 @@
_Note: Gaps between patch versions are faulty/broken releases._
## 3.3.3
* **Bug Fix**
* Remap top level `this` to `undefined` instead of throwing an error.
* Run `selfContained` transformer over the regenerator runtime when building `6to5-runtime`.
* Fix `t.isReferenced` not properly allowing `value` nodes.
## 3.3.1
* **Bug Fix**

View File

@@ -0,0 +1,22 @@
var t = require("../../types");
var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass");
exports.isCreateClass = function (node) {
if (!node || !t.isCallExpression(node)) return false;
// not React.createClass call member object
if (!isCreateClassCallExpression(node.callee)) return false;
// no call arguments
var args = node.arguments;
if (args.length !== 1) return false;
// first node arg is not an object
var first = args[0];
if (!t.isObjectExpression(first)) return false;
return true;
};
exports.isReactComponent = t.buildMatchMemberExpression("React.Component");

View File

@@ -12,6 +12,7 @@ module.exports = {
"playground.objectGetterMemoization": require("./playground/object-getter-memoization"),
react: require("./other/react"),
"optimisation.react": require("./optimisation/react"),
_modules: require("./internal/modules"),

View File

@@ -0,0 +1,55 @@
module.exports = BaseOptimiser;
var object = require("../../../../helpers/object");
/**
* Description
*
* @param {Node} node
*/
function BaseOptimiser(node) {
this.methods = object();
this.types = object();
this.node = node;
}
/**
* Description
*/
BaseOptimiser.prototype.run = function () {
this.getMethods();
this.getTypes();
};
/**
* Add an `ObjectExpression` `node` that contains `propTypes`.
*
* Search it and match it against the types that we can optimise
* and register it for consumption later.
*
* @param {Node} node
*/
BaseOptimiser.prototype.addPropTypes = function (node) {
var props = node.properties;
for (var i = 0; i < props.length; i++) {
this.addPropType(props[i]);
}
};
/**
* Register a `Property` node as a prop type.
*
* We'll try and resolve it to a known type if we can and normalise
* it for consumption later.
*
* @param {Node} prop
*/
BaseOptimiser.prototype.addPropType = function () {
};

View File

@@ -0,0 +1,51 @@
module.exports = CreateClassOptimiser;
var BaseOptimiser = require("./base");
var util = require("../../../../util");
var t = require("../../../../types");
function CreateClassOptimiser() {
BaseOptimiser.apply(this, arguments);
}
util.inherits(CreateClassOptimiser, BaseOptimiser);
/**
* Get all function expressions.
*/
CreateClassOptimiser.prototype.getMethods = function () {
var props = this.node.properties;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
// irrelevant
if (!t.isFunctionExpression(prop.value)) continue;
// deopt
if (prop.computed) continue;
this.methods[prop.key.name] = prop;
}
};
/**
* Find a `propTypes` property.
*/
CreateClassOptimiser.prototype.getTypes = function () {
var props = this.node.properties;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
var key = t.toComputedKey(prop, prop.key);
if (t.isLiteral(key, { value: "propTypes" }) && t.isObjectExpression(prop.value)) {
this.addPropTypes(prop.value);
return;
}
}
// not found
};

View File

@@ -0,0 +1,17 @@
var CreateClassOptimiser = require("./create-class");
var NativeClassOptimiser = require("./native-class");
var react = require("../../../helpers/react");
exports.optional = true;
exports.CallExpression = function (node) {
if (react.isCreateClass(node)) {
new CreateClassOptimiser(node.arguments[0]).run();
}
};
exports.CallExpression = function (node) {
if (react.isReactComponent(node.superClass)) {
new NativeClassOptimiser(node).run();
}
};

View File

@@ -0,0 +1,42 @@
module.exports = NativeClassOptimiser;
var BaseOptimiser = require("./base");
var util = require("../../../../util");
var t = require("../../../../types");
function NativeClassOptimiser() {
BaseOptimiser.apply(this, arguments);
}
util.inherits(NativeClassOptimiser, BaseOptimiser);
/**
* Get all instance methods.
*/
NativeClassOptimiser.prototype.getMethods = function () {
var body = this.node.body;
for (var i = 0; i < body.length; i++) {
var node = body[i];
// PrivateDeclaration etc
if (!t.isMethodDefinition(node)) continue;
// deopt
if (node.computed) continue;
// irrelevant
if (node.static) continue;
this.methods[node.key.name] = node;
}
};
/**
* Description
*/
NativeClassOptimiser.prototype.getTypes = function () {
};

View File

@@ -6,6 +6,7 @@
// jsx
var esutils = require("esutils");
var react = require("../../helpers/react");
var t = require("../../../types");
exports.JSXIdentifier = function (node, parent) {
@@ -197,33 +198,8 @@ var cleanJSXElementLiteralChild = function (child, args) {
// display names
var isCreateClass = function (call) {
if (!call || !t.isCallExpression(call)) return false;
var callee = call.callee;
if (!t.isMemberExpression(callee)) return false;
// not React call member object
var obj = callee.object;
if (!t.isIdentifier(obj, { name: "React" })) return false;
// not createClass call member property
var prop = callee.property;
if (!t.isIdentifier(prop, { name: "createClass" })) return false;
// no call arguments
var args = call.arguments;
if (args.length !== 1) return false;
// first call arg is not an object
var first = args[0];
if (!t.isObjectExpression(first)) return;
return true;
};
var addDisplayName = function (id, call) {
if (!isCreateClass(call)) return;
if (!react.isCreateClass(call)) return;
var props = call.arguments[0].properties;
var safe = true;

View File

@@ -16,6 +16,6 @@ exports.FunctionExpression = function (node, parent, scope, context) {
context.skip();
};
exports.ThisExpression = function (node, parent, scope, context, file) {
throw file.errorWithNode(node, "Top level `this` is `undefined` in strict mode", ReferenceError);
exports.ThisExpression = function () {
return t.identifier("undefined");
};

View File

@@ -257,8 +257,9 @@ t.isReferenced = function (node, parent) {
}
// yes: { [NODE]: "" }
if (t.isProperty(parent)) {
return parent.key === node && parent.computed;
// no: { NODE: "" }
if (t.isProperty(parent) && parent.key === node) {
return parent.computed;
}
// no: var NODE = init;
@@ -399,6 +400,65 @@ t.ensureBlock = function (node, key) {
node[key] = t.toBlock(node[key], node);
};
/**
* Build a function that when called will return whether or not the
* input `node` `MemberExpression` matches the input `match`.
*
* For example, given the match `React.createClass` it would match the
* parsed nodes of `React.createClass` and `React["createClass"]`.
*
* @param {String} match Dot delimetered string
* @param {Boolean} [allowPartial] Allow a partial match
* @returns {Function}
*/
t.buildMatchMemberExpression = function (match, allowPartial) {
var parts = match.split(".");
return function (member) {
// not a member expression
if (!t.isMemberExpression(member)) return false;
var search = [member];
var i = 0;
while (search.length) {
var node = search.shift();
if (t.isIdentifier(node)) {
// this part doesn't match
if (parts[i] !== node.name) return false;
} else if (t.isLiteral(node)) {
// this part doesn't match
if (parts[i] !== node.value) return false;
} else if (t.isMemberExpression(node)) {
if (node.computed && !t.isLiteral(node.property)) {
// we can't deal with this
return false;
} else {
search.push(node.object);
search.push(node.property);
continue;
}
} else {
// we can't deal with this
return false;
}
// too many parts
if (++i > parts.length) {
if (allowPartial) {
return true;
} else {
return false;
}
}
}
return true;
};
};
/**
* Description
*

View File

@@ -1,7 +1,7 @@
{
"name": "6to5",
"description": "Turn ES6 code into readable vanilla ES5 with source maps",
"version": "3.3.1",
"version": "3.3.3",
"author": "Sebastian McKenzie <sebmck@gmail.com>",
"homepage": "https://6to5.org/",
"repository": "6to5/6to5",

View File

@@ -1,7 +1,7 @@
{
"name": "6to5-runtime",
"description": "6to5 selfContained runtime",
"version": "3.3.0",
"version": "3.3.2",
"repository": "6to5/6to5",
"author": "Sebastian McKenzie <sebmck@gmail.com>"
}

View File

@@ -30,6 +30,12 @@ var updatePackage = function () {
writeFile("package.json", JSON.stringify(pkg, null, 2));
};
var selfContainify = function (code) {
return transform(code, {
optional: ["selfContained"]
}).code;
};
var buildHelpers2 = function () {
var body = [];
var tree = t.program(body);
@@ -44,5 +50,5 @@ var buildHelpers2 = function () {
writeFile("helpers.js", buildHelpers2());
writeFile("core-js.js", readFile("core-js/library"));
writeFile("regenerator/index.js", readFile("regenerator-6to5/runtime-module"));
writeFile("regenerator/runtime.js", readFile("regenerator-6to5/runtime"));
writeFile("regenerator/runtime.js", selfContainify(readFile("regenerator-6to5/runtime")));
updatePackage();

View File

@@ -1,3 +0,0 @@
{
"throws": "Top level `this` is `undefined` in strict mode"
}

View File

@@ -1,3 +0,0 @@
{
"throws": "Top level `this` is `undefined` in strict mode"
}

View File

@@ -1,3 +0,0 @@
{
"throws": "Top level `this` is `undefined` in strict mode"
}

View File

@@ -1,3 +0,0 @@
{
"throws": "Top level `this` is `undefined` in strict mode"
}

View File

@@ -0,0 +1,5 @@
"use strict";
var foo = function () {
return undefined;
};

View File

@@ -0,0 +1,3 @@
"use strict";
undefined.foo();

View File

@@ -0,0 +1,3 @@
"use strict";
var self = undefined;

View File

@@ -0,0 +1,3 @@
"use strict";
undefined;