babel-plugin-const-enum
Advanced tools
Comparing version 0.0.4 to 0.0.5
@@ -31,48 +31,104 @@ "use strict"; | ||
const tsEnumMember = tsEnumMemberPath.node; | ||
let value; | ||
let valueNode; | ||
const keyNode = computeKeyNodeFromIdPath(tsEnumMemberPath.get('id')); | ||
const key = getKeyFromKeyNode(keyNode); | ||
const valueNode = computeValueNodeFromEnumMemberPath(tsEnumMemberPath, isStringEnum, constEnum, currentValue); | ||
const value = getValueFromValueNode(valueNode); | ||
constEnum[key] = value; | ||
if (tsEnumMember.initializer) { | ||
if (_core.types.isNumericLiteral(tsEnumMember.initializer) || _core.types.isStringLiteral(tsEnumMember.initializer)) { | ||
value = tsEnumMember.initializer.value; | ||
} else if (_core.types.isIdentifier(tsEnumMember.initializer)) { | ||
value = constEnum[tsEnumMember.initializer.name]; | ||
validateConstEnumMemberAccess(tsEnumMemberPath, value); | ||
} else if (isNumericUnaryExpression(tsEnumMember.initializer) || isNumericBinaryExpression(tsEnumMember.initializer)) { | ||
if (isStringEnum) { | ||
throw tsEnumMemberPath.buildCodeFrameError('Computed values are not permitted in an enum with string valued members.'); | ||
} | ||
if (_core.types.isNumericLiteral(valueNode)) { | ||
currentValue = value + 1; | ||
} else if (_core.types.isStringLiteral(valueNode)) { | ||
currentValue = null; | ||
} | ||
tsEnumMemberPath.get('initializer').traverse(accessConstEnumMemberVisitor, { | ||
constEnum | ||
}); | ||
value = eval((0, _generator.default)(tsEnumMember.initializer).code); | ||
} else { | ||
throw tsEnumMemberPath.buildCodeFrameError('Enum initializer must be a string literal or numeric expression.'); | ||
} | ||
} else { | ||
if (currentValue === null) { | ||
throw tsEnumMemberPath.buildCodeFrameError('Enum member must have initializer..'); | ||
} | ||
return _core.types.objectProperty(keyNode, valueNode); | ||
}); | ||
}; | ||
value = currentValue; | ||
} | ||
const computeKeyNodeFromIdPath = idPath => { | ||
const id = idPath.node; | ||
let keyNode; | ||
constEnum[tsEnumMember.id.name] = value; | ||
if (_core.types.isIdentifier(id)) { | ||
const key = id.name; | ||
keyNode = _core.types.identifier(key); | ||
} else if (_core.types.isStringLiteral(id)) { | ||
const key = id.value; | ||
keyNode = _core.types.stringLiteral(key); | ||
} else if (_core.types.isNumericLiteral(id)) { | ||
throw idPath.buildCodeFrameError('An enum member cannot have a numeric name.'); | ||
} else { | ||
throw idPath.buildCodeFrameError('Enum member expected.'); | ||
} | ||
if (Number.isFinite(value)) { | ||
valueNode = _core.types.numericLiteral(value); | ||
currentValue = value + 1; | ||
} else if (typeof value === 'string') { | ||
valueNode = _core.types.stringLiteral(value); | ||
currentValue = null; | ||
return keyNode; | ||
}; | ||
const getKeyFromKeyNode = keyNode => { | ||
let key; | ||
if (_core.types.isIdentifier(keyNode)) { | ||
key = keyNode.name; | ||
} else if (_core.types.isStringLiteral(keyNode)) { | ||
key = keyNode.value; | ||
} | ||
return key; | ||
}; | ||
const computeValueNodeFromEnumMemberPath = (tsEnumMemberPath, isStringEnum, constEnum, currentValue) => { | ||
const initializerPath = tsEnumMemberPath.get('initializer'); | ||
const initializer = initializerPath.node; | ||
let value; | ||
if (initializer) { | ||
if (_core.types.isNumericLiteral(initializer) || _core.types.isStringLiteral(initializer)) { | ||
value = initializer.value; | ||
} else if (_core.types.isIdentifier(initializer)) { | ||
value = constEnum[initializer.name]; | ||
validateConstEnumMemberAccess(tsEnumMemberPath, value); | ||
} else if (isNumericUnaryExpression(initializer) || isNumericBinaryExpression(initializer)) { | ||
if (isStringEnum) { | ||
throw initializerPath.buildCodeFrameError('Computed values are not permitted in an enum with string valued members.'); | ||
} | ||
initializerPath.traverse(accessConstEnumMemberVisitor, { | ||
constEnum | ||
}); | ||
value = eval((0, _generator.default)(initializer).code); | ||
} else { | ||
// Should not get here. | ||
throw new Error('`value` is not a numer or string'); | ||
throw initializerPath.buildCodeFrameError('Enum initializer must be a string literal or numeric expression.'); | ||
} | ||
} else { | ||
if (currentValue === null) { | ||
throw tsEnumMemberPath.buildCodeFrameError('Enum member must have initializer..'); | ||
} | ||
return _core.types.objectProperty(_core.types.identifier(tsEnumMember.id.name), valueNode); | ||
}); | ||
value = currentValue; | ||
} | ||
let valueNode; | ||
if (Number.isFinite(value)) { | ||
valueNode = _core.types.numericLiteral(value); | ||
} else if (typeof value === 'string') { | ||
valueNode = _core.types.stringLiteral(value); | ||
} else { | ||
// Should not get here. | ||
throw new Error('`value` is not a number or string'); | ||
} | ||
return valueNode; | ||
}; | ||
const getValueFromValueNode = valueNode => { | ||
let value; | ||
if (_core.types.isNumericLiteral(valueNode) || _core.types.isStringLiteral(valueNode)) { | ||
value = valueNode.value; | ||
} | ||
return value; | ||
}; | ||
const isNumericUnaryExpression = node => _core.types.isUnaryExpression(node) && new Set(['+', '-', '~']).has(node.operator); | ||
@@ -79,0 +135,0 @@ |
{ | ||
"name": "babel-plugin-const-enum", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "Transform TypeScript `const` enums", | ||
@@ -23,3 +23,3 @@ "repository": "https://github.com/dosentmatter/babel-plugin-const-enum", | ||
"test": "jest", | ||
"prettier-fix": "prettier --write src/**/*.js" | ||
"prettier-fix": "prettier --write src/**/*.js __tests__/**/*.js" | ||
}, | ||
@@ -26,0 +26,0 @@ "peerDependencies": { |
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
11792
166