import { CharRange } from "refa" ; import { CleanRegexRule , createRuleListener , getDocUrl } from "../rules-util" ; import { isControlEscapeSequence , isHexadecimalEscapeSequence , isOctalEscapeSequence } from "../ast-util" ; const allowedRanges = [ { min : "0" . charCodeAt ( 0 ) , max : "9" . charCodeAt ( 0 ) } , { min : "A" . charCodeAt ( 0 ) , max : "Z" . charCodeAt ( 0 ) } , { min : "a" . charCodeAt ( 0 ) , max : "z" . charCodeAt ( 0 ) } , ] ; function inRange ( char , range ) { return range . min <= char && char <= range . max ; } export default { meta : { type : "problem" , docs : { description : "Disallow obscure ranges in character classes." , url : getDocUrl ( "no-obscure-range" ) , } , } , create ( context ) { return createRuleListener ( ( { visitAST , reportElement } ) => { visitAST ( { onCharacterClassRangeEnter ( node ) { const { min , max } = node ; if ( min . value == max . value ) { return ; } if ( isControlEscapeSequence ( min ) && isControlEscapeSequence ( max ) ) { return ; } if ( isOctalEscapeSequence ( min ) && isOctalEscapeSequence ( max ) ) { return ; } if ( ( isHexadecimalEscapeSequence ( min ) || min . value === 0 ) && isHexadecimalEscapeSequence ( max ) ) { return ; } if ( allowedRanges . some ( r => inRange ( min . value , r ) && inRange ( max . value , r ) ) ) { return ; } context . report ( { message : `It's not obvious what characters are matched by ${ node . raw }` , ... reportElement ( node ) , } ) ; } , } ) ; } ) ; } , } as CleanRegexRule ;