semi.js.flow 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. const schema = [
  2. {
  3. enum: ['always', 'never'],
  4. type: 'string',
  5. },
  6. ];
  7. const isSemicolon = (token) => token.type === 'Punctuator' && token.value === ';';
  8. const create = (context) => {
  9. const never = (context.options[0] || 'always') === 'never';
  10. const sourceCode = context.getSourceCode();
  11. const report = (node, missing) => {
  12. const lastToken = sourceCode.getLastToken(node);
  13. let fix;
  14. let message;
  15. let { loc } = lastToken;
  16. if (missing) {
  17. message = 'Missing semicolon.';
  18. loc = loc.end;
  19. fix = (fixer) => fixer.insertTextAfter(lastToken, ';');
  20. } else {
  21. message = 'Extra semicolon.';
  22. loc = loc.start;
  23. fix = (fixer) => fixer.remove(lastToken);
  24. }
  25. context.report({
  26. fix,
  27. loc,
  28. message,
  29. node,
  30. });
  31. };
  32. const checkForSemicolon = (node) => {
  33. const lastToken = sourceCode.getLastToken(node);
  34. const isLastTokenSemicolon = isSemicolon(lastToken);
  35. if (never && isLastTokenSemicolon) {
  36. report(node, false);
  37. }
  38. if (!never && !isLastTokenSemicolon) {
  39. report(node, true);
  40. }
  41. };
  42. return {
  43. OpaqueType: checkForSemicolon,
  44. TypeAlias: checkForSemicolon,
  45. TypeAnnotation: (node) => {
  46. if (['PropertyDefinition', 'ClassProperty'].includes(node.parent.type)) {
  47. checkForSemicolon(node.parent);
  48. }
  49. },
  50. };
  51. };
  52. export default {
  53. create,
  54. meta: {
  55. fixable: 'code',
  56. },
  57. schema,
  58. };