index.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. const path = require('path');
  2. const minimatch = require('minimatch');
  3. // Files matching these patterns will be ignored unless a rule has `static global = true`
  4. const ignore = ['contracts/mocks/**/*', 'test/**/*'];
  5. class Base {
  6. constructor(reporter, config, source, fileName) {
  7. this.reporter = reporter;
  8. this.ignored = this.constructor.global || ignore.some(p => minimatch(path.normalize(fileName), p));
  9. this.ruleId = this.constructor.ruleId;
  10. if (this.ruleId === undefined) {
  11. throw Error('missing ruleId static property');
  12. }
  13. }
  14. error(node, message) {
  15. if (!this.ignored) {
  16. this.reporter.error(node, this.ruleId, message);
  17. }
  18. }
  19. }
  20. module.exports = [
  21. class extends Base {
  22. static ruleId = 'interface-names';
  23. ContractDefinition(node) {
  24. if (node.kind === 'interface' && !/^I[A-Z]/.test(node.name)) {
  25. this.error(node, 'Interface names should have a capital I prefix');
  26. }
  27. }
  28. },
  29. class extends Base {
  30. static ruleId = 'private-variables';
  31. VariableDeclaration(node) {
  32. const constantOrImmutable = node.isDeclaredConst || node.isImmutable;
  33. if (node.isStateVar && !constantOrImmutable && node.visibility !== 'private') {
  34. this.error(node, 'State variables must be private');
  35. }
  36. }
  37. },
  38. class extends Base {
  39. static ruleId = 'leading-underscore';
  40. VariableDeclaration(node) {
  41. if (node.isDeclaredConst) {
  42. if (/^_/.test(node.name)) {
  43. // TODO: re-enable and fix
  44. // this.error(node, 'Constant variables should not have leading underscore');
  45. }
  46. } else if (node.visibility === 'private' && !/^_/.test(node.name)) {
  47. this.error(node, 'Non-constant private variables must have leading underscore');
  48. }
  49. }
  50. FunctionDefinition(node) {
  51. if (node.visibility === 'private' || (node.visibility === 'internal' && node.parent.kind !== 'library')) {
  52. if (!/^_/.test(node.name)) {
  53. this.error(node, 'Private and internal functions must have leading underscore');
  54. }
  55. }
  56. if (node.visibility === 'internal' && node.parent.kind === 'library') {
  57. if (/^_/.test(node.name)) {
  58. this.error(node, 'Library internal functions should not have leading underscore');
  59. }
  60. }
  61. }
  62. },
  63. // TODO: re-enable and fix
  64. // class extends Base {
  65. // static ruleId = 'no-external-virtual';
  66. //
  67. // FunctionDefinition(node) {
  68. // if (node.visibility == 'external' && node.isVirtual) {
  69. // this.error(node, 'Functions should not be external and virtual');
  70. // }
  71. // }
  72. // },
  73. ];