Files
2023-08-01 13:49:46 +02:00

161 lines
4.2 KiB
JavaScript

/**
* @license
* Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// jshint node: true
'use strict';
// useful tool to visualize AST: http://esprima.org/demo/parse.html
/**
* converts literal: {"type": "Literal", "value": 5, "raw": "5" }
* to string
*/
function literalToValue(literal) {
return literal.value;
}
/**
* converts unary to string
* unary: { type: 'UnaryExpression', operator: '-', argument: { ... } }
*/
function unaryToValue(unary) {
var argValue = expressionToValue(unary.argument);
if (argValue === undefined)
return;
return unary.operator + argValue;
}
/**
* converts identifier to its value
* identifier { "type": "Identifier", "name": "Number }
*/
function identifierToValue(identifier) {
return identifier.name;
}
/**
* Function is a block statement.
*/
function functionDeclarationToValue(fn) {
if (fn.body.type == "BlockStatement")
return blockStatementToValue(fn.body);
}
function functionExpressionToValue(fn) {
if (fn.body.type == "BlockStatement")
return blockStatementToValue(fn.body);
}
/**
* Block statement: find last return statement, and return its value
*/
function blockStatementToValue(block) {
for (var i=block.body.length - 1; i>= 0; i--) {
if (block.body[i].type === "ReturnStatement")
return returnStatementToValue(block.body[i]);
}
}
/**
* Evaluates return's argument
*/
function returnStatementToValue(ret) {
return expressionToValue(ret.argument);
}
/**
* Enclose containing values in []
*/
function arrayExpressionToValue(arry) {
var value = '[';
for (var i=0; i<arry.elements.length; i++) {
var v = expressionToValue(arry.elements[i]);
if (v === undefined)
continue;
if (i !== 0)
value += ', ';
value += v;
}
value += ']';
return value;
}
/**
* Make it look like an object
*/
function objectExpressionToValue(obj) {
var value = '{';
for (var i=0; i<obj.properties.length; i++) {
var k = expressionToValue(obj.properties[i].key);
var v = expressionToValue(obj.properties[i].value);
if (v === undefined)
continue;
if (i !== 0)
value += ', ';
value += '"' + k + '": ' + v;
}
value += '}';
return value;
}
/**
* BinaryExpressions are of the form "literal" + "literal"
*/
function binaryExpressionToValue(member) {
if (member.operator == "+") {
return expressionToValue(member.left) + expressionToValue(member.right);
}
return
}
/**
* MemberExpression references a variable with name
*/
function memberExpressionToValue(member) {
return expressionToValue(member.object) + "." + expressionToValue(member.property);
}
/**
* Tries to get a value from expression. Handles Literal, UnaryExpression
* returns undefined on failure
* valueExpression example:
* { type: "Literal",
*/
function expressionToValue(valueExpression) {
switch(valueExpression.type) {
case 'Literal':
return literalToValue(valueExpression);
case 'UnaryExpression':
return unaryToValue(valueExpression);
case 'Identifier':
return identifierToValue(valueExpression);
case 'FunctionDeclaration':
return functionDeclarationToValue(valueExpression);
case 'FunctionExpression':
return functionExpressionToValue(valueExpression);
case 'ArrayExpression':
return arrayExpressionToValue(valueExpression);
case 'ObjectExpression':
return objectExpressionToValue(valueExpression);
case 'Identifier':
return identifierToValue(valueExpression);
case 'MemberExpression':
return memberExpressionToValue(valueExpression);
case 'BinaryExpression':
return binaryExpressionToValue(valueExpression);
default:
return;
}
}
var CANT_CONVERT = 'UNKNOWN';
module.exports = {
CANT_CONVERT: CANT_CONVERT,
expressionToValue: expressionToValue
};