123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- 'use strict'
- var acorn = require('acorn');
- var walk = require('acorn/dist/walk');
- var lastSRC = '(null)';
- var lastRes = true;
- var lastConstants = undefined;
- var STATEMENT_WHITE_LIST = {
- 'EmptyStatement': true,
- 'ExpressionStatement': true,
- };
- var EXPRESSION_WHITE_LIST = {
- 'ParenthesizedExpression': true,
- 'ArrayExpression': true,
- 'ObjectExpression': true,
- 'SequenceExpression': true,
- 'TemplateLiteral': true,
- 'UnaryExpression': true,
- 'BinaryExpression': true,
- 'LogicalExpression': true,
- 'ConditionalExpression': true,
- 'Identifier': true,
- 'Literal': true,
- 'ComprehensionExpression': true,
- 'TaggedTemplateExpression': true,
- 'MemberExpression': true,
- 'CallExpression': true,
- 'NewExpression': true,
- };
- module.exports = isConstant;
- function isConstant(src, constants) {
- src = '(' + src + ')';
- if (lastSRC === src && lastConstants === constants) return lastRes;
- lastSRC = src;
- lastConstants = constants;
- if (!isExpression(src)) return lastRes = false;
- var ast;
- try {
- ast = acorn.parse(src, {
- ecmaVersion: 6,
- allowReturnOutsideFunction: true,
- allowImportExportEverywhere: true,
- allowHashBang: true
- });
- } catch (ex) {
- return lastRes = false;
- }
- var isConstant = true;
- walk.simple(ast, {
- Statement: function (node) {
- if (isConstant) {
- if (STATEMENT_WHITE_LIST[node.type] !== true) {
- isConstant = false;
- }
- }
- },
- Expression: function (node) {
- if (isConstant) {
- if (EXPRESSION_WHITE_LIST[node.type] !== true) {
- isConstant = false;
- }
- }
- },
- MemberExpression: function (node) {
- if (isConstant) {
- if (node.computed) isConstant = false;
- else if (node.property.name[0] === '_') isConstant = false;
- }
- },
- Identifier: function (node) {
- if (isConstant) {
- if (!constants || !(node.name in constants)) {
- isConstant = false;
- }
- }
- },
- });
- return lastRes = isConstant;
- }
- isConstant.isConstant = isConstant;
- isConstant.toConstant = toConstant;
- function toConstant(src, constants) {
- if (!isConstant(src, constants)) throw new Error(JSON.stringify(src) + ' is not constant.');
- return Function(Object.keys(constants || {}).join(','), 'return (' + src + ')').apply(null, Object.keys(constants || {}).map(function (key) {
- return constants[key];
- }));
- }
- function isExpression(src) {
- try {
- eval('throw "STOP"; (function () { return (' + src + '); })()');
- return false;
- }
- catch (err) {
- return err === 'STOP';
- }
- }
|