66
77const { rules : esRules } = require ( "eslint-plugin-es" )
88const { getInnermostScope } = require ( "eslint-utils" )
9- const semver = require ( "semver" )
10- const getEnginesNode = require ( "../../util/get-engines-node" )
9+ const { Range } = require ( "semver" ) //eslint-disable-line no-unused-vars
10+ const getConfiguredNodeVersion = require ( "../../util/get-configured-node-version" )
11+ const getSemverRange = require ( "../../util/get-semver-range" )
1112
1213const getOrSet = / ^ (?: g | s ) e t $ /
1314const features = {
@@ -353,42 +354,18 @@ const keywords = Object.keys(features)
353354
354355/**
355356 * Parses the options.
356- * @param {object|undefined } options - An option object to parse.
357- * @param {string } defaultVersion - The default version to use if the version option was omitted.
358- * @returns {{version:string,ignores:Set<string>} } Parsed value.
357+ * @param {RuleContext } context The rule context.
358+ * @returns {{version:Range,ignores:Set<string>} } Parsed value.
359359 */
360- function parseOptions ( options , defaultVersion ) {
361- const version =
362- semver . validRange ( options && options . version ) || defaultVersion
363- const ignores = new Set ( ( options && options . ignores ) || [ ] )
360+ function parseOptions ( context ) {
361+ const raw = context . options [ 0 ] || { }
362+ const filePath = context . getFilename ( )
363+ const version = getConfiguredNodeVersion ( raw . version , filePath )
364+ const ignores = new Set ( raw . ignores || [ ] )
364365
365366 return Object . freeze ( { version, ignores } )
366367}
367368
368- /**
369- * Define the case selector with given information.
370- * @param {RuleContext } context The rule context to get scopes.
371- * @param {string } version The configured version range.
372- * @param {Node|null } node The node at the current location, for additional conditions.
373- * @returns {function(aCase:object):boolean } The case selector.
374- */
375- function defineSelector ( context , version , node ) {
376- return aCase =>
377- // Version.
378- ( ! aCase . supported ||
379- semver . intersects ( `<${ aCase . supported } ` , version ) ) &&
380- // Additional conditions.
381- ( ! aCase . test ||
382- aCase . test ( {
383- node,
384- get isStrict ( ) {
385- return Boolean (
386- node && nomalizeScope ( context . getScope ( ) , node ) . isStrict
387- )
388- } ,
389- } ) )
390- }
391-
392369/**
393370 * Find the scope that a given node belongs to.
394371 * @param {Scope } initialScope The initial scope to find.
@@ -443,25 +420,47 @@ function dispatch(handlers, node) {
443420/**
444421 * Define the visitor object as merging the rules of eslint-plugin-es.
445422 * @param {RuleContext } context The rule context.
446- * @param {{version:string ,ignores:Set<string>} } options The options.
423+ * @param {{version:Range ,ignores:Set<string>} } options The options.
447424 * @returns {object } The defined visitor.
448425 */
449426function defineVisitor ( context , options ) {
427+ const testInfoPrototype = {
428+ get isStrict ( ) {
429+ return nomalizeScope ( context . getScope ( ) , this . node ) . isStrict
430+ } ,
431+ }
432+
433+ /**
434+ * Check whether a given case object is full-supported on the configured node version.
435+ * @param {{supported:string} } aCase The case object to check.
436+ * @returns {boolean } `true` if it's supporting.
437+ */
438+ function isNotSupportingVersion ( aCase ) {
439+ return (
440+ ! aCase . supported ||
441+ options . version . intersects ( getSemverRange ( `<${ aCase . supported } ` ) )
442+ )
443+ }
444+
445+ /**
446+ * Define the predicate function to check whether a given case object is supported on the configured node version.
447+ * @param {Node } node The node which is reported.
448+ * @returns {function(aCase:{supported:string}):boolean } The predicate function.
449+ */
450+ function isNotSupportingOn ( node ) {
451+ return aCase =>
452+ isNotSupportingVersion ( aCase ) &&
453+ ( ! aCase . test || aCase . test ( { node, __proto__ : testInfoPrototype } ) )
454+ }
455+
450456 return (
451457 keywords
452458 // Omit full-supported features and ignored features by options
453459 // because this rule never reports those.
454460 . filter (
455461 keyword =>
456462 ! options . ignores . has ( keyword ) &&
457- features [ keyword ] . cases . some (
458- c =>
459- ! c . supported ||
460- semver . intersects (
461- options . version ,
462- `<${ c . supported } `
463- )
464- )
463+ features [ keyword ] . cases . some ( isNotSupportingVersion )
465464 )
466465 // Merge remaining features with overriding `context.report()`.
467466 . reduce ( ( visitor , keyword ) => {
@@ -476,20 +475,15 @@ function defineVisitor(context, options) {
476475 report ( descriptor ) {
477476 // Set additional information.
478477 if ( descriptor . data ) {
479- descriptor . data . version = options . version
478+ descriptor . data . version = options . version . raw
480479 } else {
481- descriptor . data = { version : options . version }
480+ descriptor . data = { version : options . version . raw }
482481 }
483482 descriptor . fix = undefined
484483
485484 // Test and report.
486- const hitCase = cases . find (
487- defineSelector (
488- this ,
489- options . version ,
490- descriptor . node
491- )
492- )
485+ const node = descriptor . node
486+ const hitCase = cases . find ( isNotSupportingOn ( node ) )
493487 if ( hitCase ) {
494488 descriptor . messageId = hitCase . messageId
495489 descriptor . data . supported = hitCase . supported
@@ -628,8 +622,6 @@ module.exports = {
628622 } ,
629623 } ,
630624 create ( context ) {
631- const defaultVersion = getEnginesNode ( context . getFilename ( ) )
632- const options = parseOptions ( context . options [ 0 ] , defaultVersion )
633- return defineVisitor ( context , options )
625+ return defineVisitor ( context , parseOptions ( context ) )
634626 } ,
635627}
0 commit comments