eslint-plugin-o1js
Version:
o1js rules for ESLint
172 lines • 7.17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getClassName = exports.getClassBodyStatements = exports.isBannedCallExpression = exports.getFunctionName = exports.getPropertyType = exports.getSecondDecoratorValue = exports.getFirstDecoratorValue = exports.getValidDecorator = exports.getDecorators = void 0;
const types_1 = require("../types");
const node_utils_1 = require("./node-utils");
/**
* Get a list of all decorators on a node.
* @param node Node to get decorators from
* @returns A list of decorators. Returns an empty list if none are found.
*/
function getDecorators(node) {
if (((0, node_utils_1.isMethodDefinition)(node) || (0, node_utils_1.isPropertyDefinition)(node)) &&
node.decorators) {
return node.decorators;
}
return [];
}
exports.getDecorators = getDecorators;
/**
* Return an object that contains what kind of o1js decorator was used
* (e.g `@state` `@prop`, or `@arrayProp`)
* and the decorator node.
* @param node The node to get the decorators from
* @returns An object indicating what decorator was used and the node
*/
function getValidDecorator(node) {
const decorators = getDecorators(node);
for (const decorator of decorators) {
if ((0, node_utils_1.isIdentifier)(decorator.expression)) {
const decoratorName = decorator.expression.name;
const validDecorator = (0, types_1.findValidContractType)(decoratorName);
if (validDecorator) {
return {
kind: validDecorator,
decorator,
};
}
}
else if ((0, node_utils_1.isCallExpression)(decorator.expression) &&
(0, node_utils_1.isIdentifier)(decorator.expression.callee)) {
const decoratorName = decorator.expression.callee.name;
const validDecorator = (0, types_1.findValidContractType)(decoratorName);
if (validDecorator) {
return {
kind: validDecorator,
decorator,
};
}
}
}
return undefined;
}
exports.getValidDecorator = getValidDecorator;
/**
* Gets the first value of a decorator expression if it has one, otherwiser returns `undefined`.
* For example, if called on `@state(T)`, it will return `T`.
* @param decorator The specified decorator
* @returns The first value of the decorator or undefined
*/
function getFirstDecoratorValue(decorator) {
if ((0, node_utils_1.isCallExpression)(decorator.expression) &&
(0, node_utils_1.isIdentifier)(decorator.expression.callee)) {
if (decorator.expression.arguments.length > 0 &&
(0, node_utils_1.isIdentifier)(decorator.expression.arguments[0])) {
return decorator.expression.arguments[0].name;
}
}
return undefined;
}
exports.getFirstDecoratorValue = getFirstDecoratorValue;
/**
* Gets the second value of a decorator expression if it has one, otherwise returns `undefined`.
* For example, if called on `@state(T, U)`, it will return `U`
* @param decorator The specified decorator
* @returns The second value of the decorator or undefined
*/
function getSecondDecoratorValue(decorator) {
if ((0, node_utils_1.isCallExpression)(decorator.expression) &&
(0, node_utils_1.isIdentifier)(decorator.expression.callee)) {
if (decorator.expression.arguments.length >= 2 &&
(0, node_utils_1.isLiteral)(decorator.expression.arguments[1])) {
return decorator.expression.arguments[1].value;
}
}
return undefined;
}
exports.getSecondDecoratorValue = getSecondDecoratorValue;
/**
* Gets the annotated type of a node if it has one. For example, if a node has the statement
* `node: T`, it will return `T`. Otherwise return undefined.
* @param node The specified node
* @returns The type annotation of the node or undefined
*/
function getPropertyType(node) {
if ((0, node_utils_1.isPropertyDefinition)(node) && node.typeAnnotation) {
if ((0, node_utils_1.isTSTypeReference)(node.typeAnnotation.typeAnnotation) &&
(0, node_utils_1.isIdentifier)(node.typeAnnotation.typeAnnotation.typeName)) {
return node.typeAnnotation.typeAnnotation.typeName.name;
}
if ((0, node_utils_1.isTSArrayType)(node.typeAnnotation.typeAnnotation) &&
(0, node_utils_1.isTSTypeReference)(node.typeAnnotation.typeAnnotation.elementType) &&
(0, node_utils_1.isIdentifier)(node.typeAnnotation.typeAnnotation.elementType.typeName)) {
return node.typeAnnotation.typeAnnotation.elementType.typeName.name;
}
}
return undefined;
}
exports.getPropertyType = getPropertyType;
/**
* Gets the function name of a node if it has one, otherwise return undefined.
* @param node The specified node
* @returns The function name or undefined
*/
function getFunctionName(node) {
var _a;
if ((0, node_utils_1.isFunctionDeclaration)(node)) {
return (_a = node.id) === null || _a === void 0 ? void 0 : _a.name;
}
else if ((0, node_utils_1.isMethodDefinition)(node)) {
if ((0, node_utils_1.isIdentifier)(node.key)) {
return node.key.name;
}
}
else if ((0, node_utils_1.isFunctionExpression)(node) || (0, node_utils_1.isArrowFunctionExpression)(node)) {
if ((0, node_utils_1.isVariableDeclarator)(node.parent) && node.parent.init === node) {
if ((0, node_utils_1.isIdentifier)(node.parent.id))
return node.parent.id.name;
}
}
return undefined;
}
exports.getFunctionName = getFunctionName;
/**
* Checks to see if the specified `CallExpression` node uses a banned import or calls upon
* a banned function.
* @param node The specified `CallExpression` node
* @param bannedImports A set of banned imports
* @param bannedFunctions A set of banned functions
* @returns True if the `CallExpression` calls on a banned import or function or false
*/
function isBannedCallExpression(node, bannedImports, bannedFunctions) {
if ((0, node_utils_1.isMemberExpression)(node.callee)) {
if ((0, node_utils_1.isIdentifier)(node.callee.property) &&
(0, node_utils_1.isIdentifier)(node.callee.object) &&
bannedImports.has(node.callee.object.name) &&
bannedFunctions.has(node.callee.property.name)) {
return true;
}
}
else if ((0, node_utils_1.isIdentifier)(node.callee) &&
bannedFunctions.has(node.callee.name)) {
return true;
}
return false;
}
exports.isBannedCallExpression = isBannedCallExpression;
function getClassBodyStatements(node) {
if ((0, node_utils_1.isClassDeclaration)(node)) {
return node.body.body;
}
return undefined;
}
exports.getClassBodyStatements = getClassBodyStatements;
function getClassName(node) {
var _a;
if ((0, node_utils_1.isClassDeclaration)(node)) {
return (_a = node.id) === null || _a === void 0 ? void 0 : _a.name;
}
return undefined;
}
exports.getClassName = getClassName;
//# sourceMappingURL=ast-utils.js.map