| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542 | /** * @author Toru Nagashima * See LICENSE file in root directory for full license. */"use strict"const semver = require("semver")const { getInnermostScope, getPropertyName } = require("eslint-utils")const getPackageJson = require("../util/get-package-json")const VERSION_MAP = new Map([    [0.1, "0.10.0"],    [0.12, "0.12.0"],    [4, "4.0.0"],    [5, "5.0.0"],    [6, "6.0.0"],    [6.5, "6.5.0"],    [7, "7.0.0"],    [7.6, "7.6.0"],    [8, "8.0.0"],    [8.3, "8.3.0"],    [9, "9.0.0"],    [10, "10.0.0"],])const VERSION_SCHEMA = {    anyOf: [        { enum: Array.from(VERSION_MAP.keys()) },        {            type: "string",            pattern: "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$",        },    ],}const DEFAULT_VERSION = "4.0.0"const FUNC_TYPE = /^(?:Arrow)?Function(?:Declaration|Expression)$/uconst CLASS_TYPE = /^Class(?:Declaration|Expression)$/uconst DESTRUCTURING_PARENT_TYPE = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression|AssignmentExpression|VariableDeclarator)$/uconst TOPLEVEL_SCOPE_TYPE = /^(?:global|function|module)$/uconst BINARY_NUMBER = /^0[bB]/uconst OCTAL_NUMBER = /^0[oO]/uconst UNICODE_ESC = /(\\+)u\{[0-9a-fA-F]+?\}/guconst GET_OR_SET = /^(?:g|s)et$/uconst NEW_BUILTIN_TYPES = [    "Int8Array",    "Uint8Array",    "Uint8ClampedArray",    "Int16Array",    "Uint16Array",    "Int32Array",    "Uint32Array",    "Float32Array",    "Float64Array",    "DataView",    "Map",    "Set",    "WeakMap",    "WeakSet",    "Proxy",    "Reflect",    "Promise",    "Symbol",    "SharedArrayBuffer",    "Atomics",]const SUBCLASSING_TEST_TARGETS = [    "Array",    "RegExp",    "Function",    "Promise",    "Boolean",    "Number",    "String",    "Map",    "Set",]const PROPERTY_TEST_TARGETS = {    Object: [        "assign",        "is",        "getOwnPropertySymbols",        "setPrototypeOf",        "values",        "entries",        "getOwnPropertyDescriptors",    ],    String: ["raw", "fromCodePoint"],    Array: ["from", "of"],    Number: [        "isFinite",        "isInteger",        "isSafeInteger",        "isNaN",        "EPSILON",        "MIN_SAFE_INTEGER",        "MAX_SAFE_INTEGER",    ],    Math: [        "clz32",        "imul",        "sign",        "log10",        "log2",        "log1p",        "expm1",        "cosh",        "sinh",        "tanh",        "acosh",        "asinh",        "atanh",        "trunc",        "fround",        "cbrt",        "hypot",    ],    Symbol: [        "hasInstance",        "isConcatSpreadablec",        "iterator",        "species",        "replace",        "search",        "split",        "match",        "toPrimitive",        "toStringTag",        "unscopables",    ],    Atomics: [        "add",        "and",        "compareExchange",        "exchange",        "wait",        "wake",        "isLockFree",        "load",        "or",        "store",        "sub",        "xor",    ],}const REGEXP_NAMED_GROUP = /(\\*)\(\?<[_$\w]/uconst REGEXP_LOOKBEHIND = /(\\*)\(\?<[=!]/uconst REGEXP_UNICODE_PROPERTY = /(\\*)\\[pP]\{.+?\}/uconst FEATURES = {    defaultParameters: {        alias: ["syntax"],        name: "Default parameters",        node: "6.0.0",    },    restParameters: {        alias: ["syntax"],        name: "Rest parameters",        node: "6.0.0",    },    spreadOperators: {        alias: ["syntax"],        name: "Spread operators",        node: "5.0.0",    },    objectLiteralExtensions: {        alias: ["syntax"],        name: "Object literal extensions",        node: "4.0.0",    },    objectPropertyShorthandOfGetSet: {        alias: ["syntax", "objectLiteralExtensions"],        name: "Property shorthand of 'get' and 'set'",        node: "6.0.0",    },    forOf: {        alias: ["syntax"],        name: "'for..of' loops",        node: "0.12.0",    },    binaryNumberLiterals: {        alias: ["syntax"],        name: "Binary number literals",        node: "4.0.0",    },    octalNumberLiterals: {        alias: ["syntax"],        name: "Octal number literals",        node: "4.0.0",    },    templateStrings: {        alias: ["syntax"],        name: "Template strings",        node: "4.0.0",    },    regexpY: {        alias: ["syntax"],        name: "RegExp 'y' flags",        node: "6.0.0",    },    regexpU: {        alias: ["syntax"],        name: "RegExp 'u' flags",        node: "6.0.0",    },    destructuring: {        alias: ["syntax"],        name: "Destructuring",        node: "6.0.0",    },    unicodeCodePointEscapes: {        alias: ["syntax"],        name: "Unicode code point escapes",        node: "4.0.0",    },    "new.target": {        alias: ["syntax"],        name: "'new.target'",        node: "5.0.0",    },    const: {        alias: ["syntax"],        name: "'const' declarations",        node: {            sloppy: "6.0.0",            strict: "4.0.0",        },    },    let: {        alias: ["syntax"],        name: "'let' declarations",        node: {            sloppy: "6.0.0",            strict: "4.0.0",        },    },    blockScopedFunctions: {        alias: ["syntax"],        name: "Block-scoped functions",        node: {            sloppy: "6.0.0",            strict: "4.0.0",        },    },    arrowFunctions: {        alias: ["syntax"],        name: "Arrow functions",        node: "4.0.0",    },    generatorFunctions: {        alias: ["syntax"],        name: "Generator functions",        node: "4.0.0",    },    classes: {        alias: ["syntax"],        name: "Classes",        node: {            sloppy: "6.0.0",            strict: "4.0.0",        },    },    modules: {        alias: ["syntax"],        name: "Import and export declarations",        node: null,    },    exponentialOperators: {        alias: ["syntax"],        name: "Exponential operators (**)",        node: "7.0.0",    },    asyncAwait: {        alias: ["syntax"],        name: "Async functions",        node: "7.6.0",    },    trailingCommasInFunctions: {        alias: ["syntax"],        name: "Trailing commas in functions",        node: "8.0.0",    },    //------------------------------------------    templateLiteralRevision: {        alias: ["syntax"],        name: "Illegal escape sequences in taggled templates",        node: "9.0.0",    },    regexpS: {        alias: ["syntax"],        name: "RegExp 's' flags",        node: "9.0.0",    },    regexpNamedCaptureGroups: {        alias: ["syntax"],        name: "RegExp named capture groups",        node: "10.0.0",    },    regexpLookbehind: {        alias: ["syntax"],        name: "RegExp lookbehind assertions",        node: "9.0.0",    },    regexpUnicodeProperties: {        alias: ["syntax"],        name: "RegExp Unicode property escapes",        node: "10.0.0",    },    restProperties: {        alias: ["syntax"],        name: "Rest properties",        node: "8.3.0",    },    spreadProperties: {        alias: ["syntax"],        name: "Spread properties",        node: "8.3.0",    },    asyncGenerators: {        alias: ["syntax"],        name: "Async generators",        node: "10.0.0",    },    forAwaitOf: {        alias: ["syntax"],        name: "for-await-of loops",        node: "10.0.0",    },    Int8Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Int8Array'",        singular: true,        node: "0.12.0",    },    Uint8Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Uint8Array'",        singular: true,        node: "0.12.0",    },    Uint8ClampedArray: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Uint8ClampedArray'",        singular: true,        node: "0.12.0",    },    Int16Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Int16Array'",        singular: true,        node: "0.12.0",    },    Uint16Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Uint16Array'",        singular: true,        node: "0.12.0",    },    Int32Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Int32Array'",        singular: true,        node: "0.12.0",    },    Uint32Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Uint32Array'",        singular: true,        node: "0.12.0",    },    Float32Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Float32Array'",        singular: true,        node: "0.12.0",    },    Float64Array: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'Float64Array'",        singular: true,        node: "0.12.0",    },    DataView: {        alias: ["runtime", "globalObjects", "typedArrays"],        name: "'DataView'",        singular: true,        node: "0.12.0",    },    Map: {        alias: ["runtime", "globalObjects"],        name: "'Map'",        singular: true,        node: "0.12.0",    },    Set: {        alias: ["runtime", "globalObjects"],        name: "'Set'",        singular: true,        node: "0.12.0",    },    WeakMap: {        alias: ["runtime", "globalObjects"],        name: "'WeakMap'",        singular: true,        node: "0.12.0",    },    WeakSet: {        alias: ["runtime", "globalObjects"],        name: "'WeakSet'",        singular: true,        node: "0.12.0",    },    Proxy: {        alias: ["runtime", "globalObjects"],        name: "'Proxy'",        singular: true,        node: "6.0.0",    },    Reflect: {        alias: ["runtime", "globalObjects"],        name: "'Reflect'",        singular: true,        node: "6.0.0",    },    Promise: {        alias: ["runtime", "globalObjects"],        name: "'Promise'",        singular: true,        node: "0.12.0",    },    Symbol: {        alias: ["runtime", "globalObjects"],        name: "'Symbol'",        singular: true,        node: "0.12.0",    },    SharedArrayBuffer: {        alias: ["runtime", "globalObjects"],        name: "'SharedArrayBuffer'",        singular: true,        node: "9.0.0",    },    Atomics: {        alias: ["runtime", "globalObjects"],        name: "'Atomics'",        singular: true,        node: "9.0.0",    },    "Object.assign": {        alias: ["runtime", "staticMethods", "Object.*"],        name: "'Object.assign'",        singular: true,        node: "4.0.0",    },    "Object.is": {        alias: ["runtime", "staticMethods", "Object.*"],        name: "'Object.is'",        singular: true,        node: "0.12.0",    },    "Object.getOwnPropertySymbols": {        alias: ["runtime", "staticMethods", "Object.*"],        name: "'Object.getOwnPropertySymbols'",        singular: true,        node: "0.12.0",    },    "Object.setPrototypeOf": {        alias: ["runtime", "staticMethods", "Object.*"],        name: "'Object.setPrototypeOf'",        singular: true,        node: "0.12.0",    },    "Object.values": {        alias: ["runtime", "staticMethods", "Object.*"],        name: "'Object.values'",        singular: true,        node: "7.0.0",    },    "Object.entries": {        alias: ["runtime", "staticMethods", "Object.*"],        name: "'Object.entries'",        singular: true,        node: "7.0.0",    },    "Object.getOwnPropertyDescriptors": {        alias: ["runtime", "staticMethods", "Object.*"],        name: "'Object.getOwnPropertyDescriptors'",        singular: true,        node: "7.0.0",    },    "String.raw": {        alias: ["runtime", "staticMethods", "String.*"],        name: "'String.raw'",        singular: true,        node: "4.0.0",    },    "String.fromCodePoint": {        alias: ["runtime", "staticMethods", "String.*"],        name: "'String.fromCodePoint'",        singular: true,        node: "4.0.0",    },    "Array.from": {        alias: ["runtime", "staticMethods", "Array.*"],        name: "'Array.from'",        singular: true,        node: "4.0.0",    },    "Array.of": {        alias: ["runtime", "staticMethods", "Array.*"],        name: "'Array.of'",        singular: true,        node: "4.0.0",    },    "Number.isFinite": {        alias: ["runtime", "staticMethods", "Number.*"],        name: "'Number.isFinite'",        singular: true,        node: "0.10.0",    },    "Number.isInteger": {        alias: ["runtime", "staticMethods", "Number.*"],        name: "'Number.isInteger'",        singular: true,        node: "0.12.0",    },    "Number.isSafeInteger": {        alias: ["runtime", "staticMethods", "Number.*"],        name: "'Number.isSafeInteger'",        singular: true,        node: "0.12.0",    },    "Number.isNaN": {        alias: ["runtime", "staticMethods", "Number.*"],        name: "'Number.isNaN'",        singular: true,        node: "0.10.0",    },    "Number.EPSILON": {        alias: ["runtime", "staticMethods", "Number.*"],        name: "'Number.EPSILON'",        singular: true,        node: "0.12.0",    },    "Number.MIN_SAFE_INTEGER": {        alias: ["runtime", "staticMethods", "Number.*"],        name: "'Number.MIN_SAFE_INTEGER'",        singular: true,        node: "0.12.0",    },    "Number.MAX_SAFE_INTEGER": {        alias: ["runtime", "staticMethods", "Number.*"],        name: "'Number.MAX_SAFE_INTEGER'",        singular: true,        node: "0.12.0",    },    "Math.clz32": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.clz32'",        singular: true,        node: "0.12.0",    },    "Math.imul": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.imul'",        singular: true,        node: "0.12.0",    },    "Math.sign": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.sign'",        singular: true,        node: "0.12.0",    },    "Math.log10": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.log10'",        singular: true,        node: "0.12.0",    },    "Math.log2": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.log2'",        singular: true,        node: "0.12.0",    },    "Math.log1p": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.log1p'",        singular: true,        node: "0.12.0",    },    "Math.expm1": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.expm1'",        singular: true,        node: "0.12.0",    },    "Math.cosh": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.cosh'",        singular: true,        node: "0.12.0",    },    "Math.sinh": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.sinh'",        singular: true,        node: "0.12.0",    },    "Math.tanh": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.tanh'",        singular: true,        node: "0.12.0",    },    "Math.acosh": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.acosh'",        singular: true,        node: "0.12.0",    },    "Math.asinh": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.asinh'",        singular: true,        node: "0.12.0",    },    "Math.atanh": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.atanh'",        singular: true,        node: "0.12.0",    },    "Math.trunc": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.trunc'",        singular: true,        node: "0.12.0",    },    "Math.fround": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.fround'",        singular: true,        node: "0.12.0",    },    "Math.cbrt": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.cbrt'",        singular: true,        node: "0.12.0",    },    "Math.hypot": {        alias: ["runtime", "staticMethods", "Math.*"],        name: "'Math.hypot'",        singular: true,        node: "0.12.0",    },    "Symbol.hasInstance": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.hasInstance'",        singular: true,        node: "6.5.0",    },    "Symbol.isConcatSpreadablec": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.isConcatSpreadablec'",        singular: true,        node: "6.0.0",    },    "Symbol.iterator": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.iterator'",        singular: true,        node: "0.12.0",    },    "Symbol.species": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.species'",        singular: true,        node: "6.5.0",    },    "Symbol.replace": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.replace'",        singular: true,        node: "6.0.0",    },    "Symbol.search": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.search'",        singular: true,        node: "6.0.0",    },    "Symbol.split": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.split'",        singular: true,        node: "6.0.0",    },    "Symbol.match": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.match'",        singular: true,        node: "6.0.0",    },    "Symbol.toPrimitive": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.toPrimitive'",        singular: true,        node: "6.0.0",    },    "Symbol.toStringTag": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.toStringTag'",        singular: true,        node: "6.0.0",    },    "Symbol.unscopables": {        alias: ["runtime", "staticMethods", "Symbol.*"],        name: "'Symbol.unscopables'",        singular: true,        node: "4.0.0",    },    "Atomics.add": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.add'",        singular: true,        node: "9.0.0",    },    "Atomics.and": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.and'",        singular: true,        node: "9.0.0",    },    "Atomics.compareExchange": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.compareExchange'",        singular: true,        node: "9.0.0",    },    "Atomics.exchange": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.exchange'",        singular: true,        node: "9.0.0",    },    "Atomics.wait": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.wait'",        singular: true,        node: "9.0.0",    },    "Atomics.wake": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.wake'",        singular: true,        node: "9.0.0",    },    "Atomics.isLockFree": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.isLockFree'",        singular: true,        node: "9.0.0",    },    "Atomics.load": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.load'",        singular: true,        node: "9.0.0",    },    "Atomics.or": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.or'",        singular: true,        node: "9.0.0",    },    "Atomics.store": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.store'",        singular: true,        node: "9.0.0",    },    "Atomics.sub": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.sub'",        singular: true,        node: "9.0.0",    },    "Atomics.xor": {        alias: ["runtime", "staticMethods", "Atomics.*"],        name: "'Atomics.xor'",        singular: true,        node: "9.0.0",    },    extendsArray: {        alias: ["runtime", "extends"],        name: "Subclassing of 'Array'",        singular: true,        node: "6.0.0",    },    extendsRegExp: {        alias: ["runtime", "extends"],        name: "Subclassing of 'RegExp'",        singular: true,        node: "5.0.0",    },    extendsFunction: {        alias: ["runtime", "extends"],        name: "Subclassing of 'Function'",        singular: true,        node: "6.0.0",    },    extendsPromise: {        alias: ["runtime", "extends"],        name: "Subclassing of 'Promise'",        singular: true,        node: "5.0.0",    },    extendsBoolean: {        alias: ["runtime", "extends"],        name: "Subclassing of 'Boolean'",        singular: true,        node: "4.0.0",    },    extendsNumber: {        alias: ["runtime", "extends"],        name: "Subclassing of 'Number'",        singular: true,        node: "4.0.0",    },    extendsString: {        alias: ["runtime", "extends"],        name: "Subclassing of 'String'",        singular: true,        node: "4.0.0",    },    extendsMap: {        alias: ["runtime", "extends"],        name: "Subclassing of 'Map'",        singular: true,        node: "4.0.0",    },    extendsSet: {        alias: ["runtime", "extends"],        name: "Subclassing of 'Set'",        singular: true,        node: "4.0.0",    },    extendsNull: {        alias: ["runtime", "extends"],        name: "'extends null'",        singular: true,        node: null,    },}const OPTIONS = Object.keys(FEATURES)/** * Gets default version configuration of this rule. * * This finds and reads 'package.json' file, then parses 'engines.node' field. * If it's nothing, this returns null. * * @param {string} filename - The file name of the current linting file. * @returns {string} The default version configuration. */function getDefaultVersion(filename) {    const info = getPackageJson(filename)    const nodeVersion = info && info.engines && info.engines.node    return semver.validRange(nodeVersion) || DEFAULT_VERSION}/** * Gets values of the `ignores` option. * * @returns {string[]} Values of the `ignores` option. */function getIgnoresEnum() {    return Object.keys(        OPTIONS.reduce((retv, key) => {            for (const alias of FEATURES[key].alias) {                retv[alias] = true            }            retv[key] = true            return retv        }, Object.create(null))    )}/** * Checks whether a given key should be ignored or not. * * @param {string} key - A key to check. * @param {string[]} ignores - An array of keys and aliases to be ignored. * @returns {boolean} `true` if the key should be ignored. */function isIgnored(key, ignores) {    return (        ignores.indexOf(key) !== -1 ||        FEATURES[key].alias.some(alias => ignores.indexOf(alias) !== -1)    )}/** * Parses the options. * * @param {number|string|object|undefined} options - An option object to parse. * @param {number} defaultVersion - The default version to use if the version option was omitted. * @returns {object} Parsed value. */function parseOptions(options, defaultVersion) {    let version = null    let range = null    let ignores = []    if (typeof options === "number") {        version = VERSION_MAP.get(options)    } else if (typeof options === "string") {        version = options    } else if (typeof options === "object") {        version =            typeof options.version === "number"                ? VERSION_MAP.get(options.version)                : options.version        ignores = options.ignores || []    }    range = semver.validRange(version ? `>=${version}` : defaultVersion)    if (!version) {        version = defaultVersion    }    return Object.freeze({        version,        features: Object.freeze(            OPTIONS.reduce((retv, key) => {                const feature = FEATURES[key]                if (isIgnored(key, ignores)) {                    retv[key] = Object.freeze({                        name: feature.name,                        singular: Boolean(feature.singular),                        supported: true,                        supportedInStrict: true,                    })                } else if (typeof feature.node === "string") {                    retv[key] = Object.freeze({                        name: feature.name,                        singular: Boolean(feature.singular),                        supported: !semver.intersects(                            range,                            `<${feature.node}`                        ),                        supportedInStrict: !semver.intersects(                            range,                            `<${feature.node}`                        ),                    })                } else {                    retv[key] = Object.freeze({                        name: feature.name,                        singular: Boolean(feature.singular),                        supported:                            feature.node != null &&                            feature.node.sloppy != null &&                            !semver.intersects(                                range,                                `<${feature.node.sloppy}`                            ),                        supportedInStrict:                            feature.node != null &&                            feature.node.strict != null &&                            !semver.intersects(                                range,                                `<${feature.node.strict}`                            ),                    })                }                return retv            }, Object.create(null))        ),    })}/** * Find the scope that a given node belongs to. * @param {Scope} initialScope The initial scope to find. * @param {Node} node The AST node. * @returns {Scope} The scope that the node belongs to. */function normalizeScope(initialScope, node) {    let scope = getInnermostScope(initialScope, node)    while (scope && scope.block === node) {        scope = scope.upper    }    return scope}/** * Checks whether the given string has `\u{90ABCDEF}`-like escapes. * * @param {string} raw - The string to check. * @returns {boolean} `true` if the string has Unicode code point escapes. */function hasUnicodeCodePointEscape(raw) {    let match = null    UNICODE_ESC.lastIndex = 0    while ((match = UNICODE_ESC.exec(raw)) != null) {        if (match[1].length % 2 === 1) {            return true        }    }    return false}/** * Check a given string has a given pattern. * @param {string} s A string to check. * @param {RegExp} pattern A RegExp object to check. * @returns {boolean} `true` if the string has the pattern. */function hasPattern(s, pattern) {    const m = pattern.exec(s)    return m != null && (m[1] || "").length % 2 === 0}module.exports = {    meta: {        docs: {            description:                "disallow unsupported ECMAScript features on the specified version",            category: "Possible Errors",            recommended: false,            replacedBy: [                "node/no-unsupported-features/es-syntax",                "node/no-unsupported-features/es-builtins",            ],            url:                "https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-unsupported-features.md",        },        type: "problem",        deprecated: true,        fixable: null,        schema: [            {                anyOf: [                    VERSION_SCHEMA.anyOf[0],                    VERSION_SCHEMA.anyOf[1],                    {                        type: "object",                        properties: {                            version: VERSION_SCHEMA,                            ignores: {                                type: "array",                                items: { enum: getIgnoresEnum() },                                uniqueItems: true,                            },                        },                        additionalProperties: false,                    },                ],            },        ],    },    create(context) {        const sourceCode = context.getSourceCode()        const supportInfo = parseOptions(            context.options[0],            getDefaultVersion(context.getFilename())        )        /**         * Gets the references of the specified global variables.         *         * @param {string[]} names - Variable names to get.         * @returns {void}         */        function* getReferences(names) {            const globalScope = context.getScope()            for (const name of names) {                const variable = globalScope.set.get(name)                if (variable && variable.defs.length === 0) {                    yield* variable.references                }            }        }        /**         * Checks whether the given function has trailing commas or not.         *         * @param {ASTNode} node - The function node to check.         * @returns {boolean} `true` if the function has trailing commas.         */        function hasTrailingCommaForFunction(node) {            const length = node.params.length            return (                length >= 1 &&                sourceCode.getTokenAfter(node.params[length - 1]).value === ","            )        }        /**         * Checks whether the given call expression has trailing commas or not.         *         * @param {ASTNode} node - The call expression node to check.         * @returns {boolean} `true` if the call expression has trailing commas.         */        function hasTrailingCommaForCall(node) {            return (                node.arguments.length >= 1 &&                sourceCode.getLastToken(node, 1).value === ","            )        }        /**         * Checks whether the given class extends from null or not.         *         * @param {ASTNode} node - The class node to check.         * @returns {boolean} `true` if the class extends from null.         */        function extendsNull(node) {            return (                node.superClass != null &&                node.superClass.type === "Literal" &&                node.superClass.value === null            )        }        /**         * Reports a given node if the specified feature is not supported.         *         * @param {ASTNode} node - A node to be reported.         * @param {string} key - A feature name to report.         * @returns {void}         */        function report(node, key) {            const version = supportInfo.version            const feature = supportInfo.features[key]            if (feature.supported) {                return            }            if (!feature.supportedInStrict) {                context.report({                    node,                    message:                        "{{feature}} {{be}} not supported yet on Node {{version}}.",                    data: {                        feature: feature.name,                        be: feature.singular ? "is" : "are",                        version,                    },                })            } else if (!normalizeScope(context.getScope(), node).isStrict) {                context.report({                    node,                    message:                        "{{feature}} {{be}} not supported yet on Node {{version}}.",                    data: {                        feature: `${feature.name} in non-strict mode`,                        be: feature.singular ? "is" : "are",                        version,                    },                })            }        }        /**         * Validate RegExp syntax.         * @param {string} pattern A RegExp pattern to check.         * @param {string} flags A RegExp flags to check.         * @param {ASTNode} node A node to report.         * @returns {void}         */        function validateRegExp(pattern, flags, node) {            if (typeof pattern === "string") {                if (hasPattern(pattern, REGEXP_NAMED_GROUP)) {                    report(node, "regexpNamedCaptureGroups")                }                if (hasPattern(pattern, REGEXP_LOOKBEHIND)) {                    report(node, "regexpLookbehind")                }                if (hasPattern(pattern, REGEXP_UNICODE_PROPERTY)) {                    report(node, "regexpUnicodeProperties")                }            }            if (typeof flags === "string") {                if (flags.indexOf("y") !== -1) {                    report(node, "regexpY")                }                if (flags.indexOf("u") !== -1) {                    report(node, "regexpU")                }                if (flags.indexOf("s") !== -1) {                    report(node, "regexpS")                }            }        }        /**         * Validate RegExp syntax in a RegExp literal.         * @param {ASTNode} node A Literal node to check.         * @returns {void}         */        function validateRegExpLiteral(node) {            validateRegExp(node.regex.pattern, node.regex.flags, node)        }        /**         * Validate RegExp syntax in the first argument of `new RegExp()`.         * @param {ASTNode} node A NewExpression node to check.         * @returns {void}         */        function validateRegExpString(node) {            const patternNode = node.arguments[0]            const flagsNode = node.arguments[1]            const pattern =                patternNode &&                patternNode.type === "Literal" &&                typeof patternNode.value === "string"                    ? patternNode.value                    : null            const flags =                flagsNode &&                flagsNode.type === "Literal" &&                typeof flagsNode.value === "string"                    ? flagsNode.value                    : null            validateRegExp(pattern, flags, node)        }        return {            "Program:exit"() {                // Check new global variables.                for (const name of NEW_BUILTIN_TYPES) {                    for (const reference of getReferences([name])) {                        // Ignore if it's using new static methods.                        const node = reference.identifier                        const parentNode = node.parent                        const properties = PROPERTY_TEST_TARGETS[name]                        if (                            properties &&                            parentNode.type === "MemberExpression"                        ) {                            const propertyName = getPropertyName(parentNode)                            if (properties.indexOf(propertyName) !== -1) {                                continue                            }                        }                        report(reference.identifier, name)                    }                }                // Check static methods.                for (const reference of getReferences(                    Object.keys(PROPERTY_TEST_TARGETS)                )) {                    const node = reference.identifier                    const parentNode = node.parent                    if (                        parentNode.type !== "MemberExpression" ||                        parentNode.object !== node                    ) {                        continue                    }                    const objectName = node.name                    const properties = PROPERTY_TEST_TARGETS[objectName]                    const propertyName = getPropertyName(parentNode)                    if (                        propertyName &&                        properties.indexOf(propertyName) !== -1                    ) {                        report(parentNode, `${objectName}.${propertyName}`)                    }                }                // Check subclassing                for (const reference of getReferences(                    SUBCLASSING_TEST_TARGETS                )) {                    const node = reference.identifier                    const parentNode = node.parent                    if (                        CLASS_TYPE.test(parentNode.type) &&                        parentNode.superClass === node                    ) {                        report(node, `extends${node.name}`)                    }                }            },            ArrowFunctionExpression(node) {                report(node, "arrowFunctions")                if (node.async) {                    report(node, "asyncAwait")                }                if (hasTrailingCommaForFunction(node)) {                    report(node, "trailingCommasInFunctions")                }            },            AssignmentPattern(node) {                if (FUNC_TYPE.test(node.parent.type)) {                    report(node, "defaultParameters")                }            },            FunctionDeclaration(node) {                const scope = context.getScope().upper                if (!TOPLEVEL_SCOPE_TYPE.test(scope.type)) {                    report(node, "blockScopedFunctions")                }                if (node.generator) {                    report(node, "generatorFunctions")                }                if (node.async) {                    report(node, "asyncAwait")                }                if (hasTrailingCommaForFunction(node)) {                    report(node, "trailingCommasInFunctions")                }                if (node.async && node.generator) {                    report(node, "asyncGenerators")                }            },            FunctionExpression(node) {                if (node.generator) {                    report(node, "generatorFunctions")                }                if (node.async) {                    report(node, "asyncAwait")                }                if (hasTrailingCommaForFunction(node)) {                    report(node, "trailingCommasInFunctions")                }                if (node.async && node.generator) {                    report(node, "asyncGenerators")                }            },            MetaProperty(node) {                const meta = node.meta.name || node.meta                const property = node.property.name || node.property                if (meta === "new" && property === "target") {                    report(node, "new.target")                }            },            ClassDeclaration(node) {                report(node, "classes")                if (extendsNull(node)) {                    report(node, "extendsNull")                }            },            ClassExpression(node) {                report(node, "classes")                if (extendsNull(node)) {                    report(node, "extendsNull")                }            },            ForOfStatement(node) {                report(node, "forOf")                if (node.await) {                    report(node, "forAwaitOf")                }            },            VariableDeclaration(node) {                if (node.kind === "const") {                    report(node, "const")                } else if (node.kind === "let") {                    report(node, "let")                }            },            ArrayPattern(node) {                if (DESTRUCTURING_PARENT_TYPE.test(node.parent.type)) {                    report(node, "destructuring")                }            },            AssignmentExpression(node) {                if (node.operator === "**=") {                    report(node, "exponentialOperators")                }            },            AwaitExpression(node) {                report(node, "asyncAwait")            },            BinaryExpression(node) {                if (node.operator === "**") {                    report(node, "exponentialOperators")                }            },            CallExpression(node) {                if (hasTrailingCommaForCall(node)) {                    report(node, "trailingCommasInFunctions")                }            },            Identifier(node) {                const raw = sourceCode.getText(node)                if (hasUnicodeCodePointEscape(raw)) {                    report(node, "unicodeCodePointEscapes")                }            },            Literal(node) {                if (typeof node.value === "number") {                    if (BINARY_NUMBER.test(node.raw)) {                        report(node, "binaryNumberLiterals")                    } else if (OCTAL_NUMBER.test(node.raw)) {                        report(node, "octalNumberLiterals")                    }                } else if (typeof node.value === "string") {                    if (hasUnicodeCodePointEscape(node.raw)) {                        report(node, "unicodeCodePointEscapes")                    }                } else if (node.regex) {                    validateRegExpLiteral(node)                }            },            NewExpression(node) {                if (                    node.callee.type === "Identifier" &&                    node.callee.name === "RegExp"                ) {                    validateRegExpString(node)                }                if (hasTrailingCommaForCall(node)) {                    report(node, "trailingCommasInFunctions")                }            },            ObjectPattern(node) {                if (DESTRUCTURING_PARENT_TYPE.test(node.parent.type)) {                    report(node, "destructuring")                }            },            Property(node) {                if (                    node.parent.type === "ObjectExpression" &&                    (node.computed || node.shorthand || node.method)                ) {                    if (node.shorthand && GET_OR_SET.test(node.key.name)) {                        report(node, "objectPropertyShorthandOfGetSet")                    } else {                        report(node, "objectLiteralExtensions")                    }                }            },            RestElement(node) {                if (FUNC_TYPE.test(node.parent.type)) {                    report(node, "restParameters")                } else if (node.parent.type === "ObjectPattern") {                    report(node, "restProperties")                }            },            SpreadElement(node) {                if (node.parent.type === "ObjectExpression") {                    report(node, "spreadProperties")                } else {                    report(node, "spreadOperators")                }            },            TemplateElement(node) {                if (node.value.cooked == null) {                    report(node, "templateLiteralRevision")                }            },            TemplateLiteral(node) {                report(node, "templateStrings")            },            ExperimentalRestProperty(node) {                report(node, "restProperties")            },            ExperimentalSpreadProperty(node) {                report(node, "spreadProperties")            },            RestProperty(node) {                report(node, "restProperties")            },            SpreadProperty(node) {                report(node, "spreadProperties")            },            ExportAllDeclaration(node) {                report(node, "modules")            },            ExportDefaultDeclaration(node) {                report(node, "modules")            },            ExportNamedDeclaration(node) {                report(node, "modules")            },            ImportDeclaration(node) {                report(node, "modules")            },        }    },}
 |