babel-plugin-aexpr-source-transformation
Advanced tools
Comparing version 1.0.0 to 1.0.1
@@ -7,33 +7,135 @@ "use strict"; | ||
exports.default = function (_ref) { | ||
var t = _ref.types; | ||
exports.default = function (param) { | ||
var t = param.types; | ||
var template = param.template; | ||
console.log(arguments); | ||
function getPropertyFromMemberExpression(node) { | ||
// We are looking for MemberExpressions, which have two distinct incarnations: | ||
// 1. we have a computed MemberExpression like a[b], with the property being an Expression | ||
// 2. a non-computed MemberExpression like a.b, with the property being an Identifier | ||
return node.computed ? | ||
// We can easily deal with the first case by replacing the MemberExpression with a call | ||
node.property : | ||
// In the second case, we introduce a StringLiteral matching the Identifier | ||
t.stringLiteral(node.property.name); | ||
} | ||
var GENERATED_FUNCTION = Symbol("generated function"); | ||
function isGenerated(path) { | ||
return path.findParent(function (p) { | ||
return t.isFunctionDeclaration(p.node) && p.node[GENERATED_FUNCTION]; | ||
}); | ||
} | ||
var customTemplates = {}; | ||
customTemplates[SET_MEMBER] = template("\n (function(obj, prop, operator, val) {\n return obj[prop] = val;\n });\n"); | ||
customTemplates[GET_MEMBER] = template("\n (function(obj, prop) {\n return obj[prop];\n });\n"); | ||
customTemplates[GET_AND_CALL_MEMBER] = template("\n (function(obj, prop, args) {\n return obj[prop](...args)\n });\n"); | ||
function addCustomTemplate(file, name) { | ||
var declar = file.declarations[name]; | ||
if (declar) return declar; | ||
var ref = customTemplates[name]; | ||
var uid = file.declarations[name] = file.scope.generateUidIdentifier(name); | ||
ref = ref().expression; | ||
ref[GENERATED_FUNCTION] = true; | ||
if (t.isFunctionExpression(ref) && !ref.id) { | ||
ref.body._compact = true; | ||
ref._generated = true; | ||
ref.id = uid; | ||
ref.type = "FunctionDeclaration"; | ||
file.path.unshiftContainer("body", ref); | ||
} else { | ||
ref._compact = true; | ||
file.scope.push({ | ||
id: uid, | ||
init: ref, | ||
unique: true | ||
}); | ||
} | ||
return uid; | ||
} | ||
return { | ||
visitor: { | ||
// TODO: also | ||
Identifier: function Identifier(path) { | ||
// The identifier should have the expected name | ||
if (path.node.name !== LOCALS_NAME) { | ||
return; | ||
//if(RESERVED_IDENTIFIERS.includes(path.node.name)) { return; } | ||
if (t.isClassDeclaration(path.parent)) { | ||
console.log("classDecl", path.node.name); | ||
return; | ||
} | ||
// The identifier should not be part of a declaration | ||
if (t.isClassMethod(path.parent)) { | ||
console.log("classMethod", path.node.name); | ||
return; | ||
} | ||
if (t.isObjectMethod(path.parent)) { | ||
console.log("objectMethod", path.node.name); | ||
return; | ||
} | ||
if (t.isVariableDeclarator(path.parent)) { | ||
console.log("varDecl", path.node.name); | ||
return; | ||
} | ||
// is this correct here? | ||
// TODO: is it correct for the locals plugin? | ||
if (!path.isReferencedIdentifier()) { | ||
console.log("def", path.node.name); | ||
return; | ||
} | ||
// The identifier should not reference a variable in current scope | ||
if (path.scope.hasBinding(LOCALS_NAME)) { | ||
// is locally defined variable? | ||
if (path.scope.hasBinding(path.node.name)) { | ||
console.log("local", path.node.name); | ||
} else { | ||
// we have a global | ||
console.log("global", path.node.name); | ||
} | ||
}, | ||
AssignmentExpression: function AssignmentExpression(path, state) { | ||
// check, whether we assign to a member (no support for pattern right now) | ||
if (!t.isMemberExpression(path.node.left)) { | ||
return; | ||
} | ||
if (isGenerated(path)) { | ||
return; | ||
} | ||
// console.log('locals expanded to', Object.keys(path.scope.getAllBindings())); | ||
path.replaceWith(t.callExpression(addCustomTemplate(state.file, SET_MEMBER), [path.node.left.object, getPropertyFromMemberExpression(path.node.left), t.stringLiteral(path.node.operator), path.node.right])); | ||
}, | ||
MemberExpression: function MemberExpression(path, state) { | ||
// lval (left values) are ignored for now | ||
if (t.isAssignmentExpression(path.parent) && path.key === 'left') { | ||
return; | ||
} | ||
if (isGenerated(path)) { | ||
return; | ||
} | ||
var vars = Object.keys(path.scope.getAllBindings()).map(function (label) { | ||
return t.objectProperty(t.identifier(label), // key | ||
t.identifier(label), // value | ||
undefined, // computed? | ||
true, // shorthand? | ||
undefined // decorators array | ||
); | ||
}); | ||
path.replaceWith(t.callExpression(addCustomTemplate(state.file, GET_MEMBER), [path.node.object, getPropertyFromMemberExpression(path.node)])); | ||
}, | ||
CallExpression: function CallExpression(path, state) { | ||
// check whether we call a MemberExpression | ||
if (!t.isMemberExpression(path.node.callee)) { | ||
return; | ||
} | ||
if (isGenerated(path)) { | ||
return; | ||
} | ||
path.replaceWith(t.objectExpression(vars)); | ||
path.replaceWith(t.callExpression(addCustomTemplate(state.file, GET_AND_CALL_MEMBER), [path.node.callee.object, getPropertyFromMemberExpression(path.node.callee), t.arrayExpression(path.node.arguments)])); | ||
} | ||
@@ -44,2 +146,10 @@ } | ||
var LOCALS_NAME = "locals"; | ||
var SET_MEMBER = "setMember"; | ||
var GET_MEMBER = "getMember"; | ||
var GET_AND_CALL_MEMBER = "getAndCallMember"; | ||
// const SET_LOCAL = "setLocal"; | ||
// const GET_LOCAL = "getLocal"; | ||
// const SET_GLOBAL = "setGlobal"; | ||
// const GET_GLOBAL = "getGlobal"; |
{ | ||
"name": "babel-plugin-aexpr-source-transformation", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "3rd implementation strategy of active expressions, via a babel transformation", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17313
406