deno_lint 0.37.0

lint for deno
Documentation
// Copyright 2020-2021 the Deno authors. All rights reserved. MIT license.
use super::{Context, LintRule};
use crate::handler::{Handler, Traverse};
use crate::{Program, ProgramRef};
use deno_ast::{view as ast_view, SourceRanged};
use std::sync::Arc;

#[derive(Debug)]
pub struct NoEmptyEnum;

const CODE: &str = "no-empty-enum";
const MESSAGE: &str = "An empty enum is equivalent to `{}`. Remove this enum or add members to this enum.";

impl LintRule for NoEmptyEnum {
  fn new() -> Arc<Self> {
    Arc::new(NoEmptyEnum)
  }

  fn tags(&self) -> &'static [&'static str] {
    &["recommended"]
  }

  fn code(&self) -> &'static str {
    CODE
  }

  fn lint_program<'view>(
    &self,
    _context: &mut Context<'view>,
    _program: ProgramRef<'view>,
  ) {
    unreachable!();
  }

  fn lint_program_with_ast_view(
    &self,
    context: &mut Context,
    program: Program<'_>,
  ) {
    NoEmptyEnumHandler.traverse(program, context);
  }

  #[cfg(feature = "docs")]
  fn docs(&self) -> &'static str {
    include_str!("../../docs/rules/no_empty_enum.md")
  }
}

struct NoEmptyEnumHandler;

impl Handler for NoEmptyEnumHandler {
  fn ts_enum_decl(
    &mut self,
    enum_decl: &ast_view::TsEnumDecl,
    ctx: &mut Context,
  ) {
    if enum_decl.members.is_empty() {
      ctx.add_diagnostic(enum_decl.range(), CODE, MESSAGE);
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn no_empty_enum_valid() {
    assert_lint_ok! {
      NoEmptyEnum,
      "enum Foo { ONE = 'ONE', TWO = 'TWO' }",
      "const enum Foo { ONE = 'ONE' }",
    };
  }

  #[test]
  fn no_empty_enum_invalid() {
    assert_lint_err! {
      NoEmptyEnum,
      "enum Foo {}": [
        {
          col: 0,
          message: MESSAGE,
        }
      ],
      "const enum Foo {}": [
        {
          col: 0,
          message: MESSAGE,
        }
      ],
      r#"
enum Foo {
  One = 1,
  Two = (() => {
    enum Bar {}
    return 42;
  })(),
}
"#: [
        {
          line: 5,
          col: 4,
          message: MESSAGE,
        }
      ],
      "export enum Foo {}": [
        {
          col: 7,
          message: MESSAGE,
        }
      ],
      "export const enum Foo {}": [
        {
          col: 7,
          message: MESSAGE,
        }
      ]
    };
  }
}