no-unsupported-features.js 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  1. /**
  2. * @author Toru Nagashima
  3. * See LICENSE file in root directory for full license.
  4. */
  5. "use strict"
  6. const semver = require("semver")
  7. const {
  8. getInnermostScope,
  9. getPropertyName,
  10. } = require("@eslint-community/eslint-utils")
  11. const getPackageJson = require("../util/get-package-json")
  12. const VERSION_MAP = new Map([
  13. [0.1, "0.10.0"],
  14. [0.12, "0.12.0"],
  15. [4, "4.0.0"],
  16. [5, "5.0.0"],
  17. [6, "6.0.0"],
  18. [6.5, "6.5.0"],
  19. [7, "7.0.0"],
  20. [7.6, "7.6.0"],
  21. [8, "8.0.0"],
  22. [8.3, "8.3.0"],
  23. [9, "9.0.0"],
  24. [10, "10.0.0"],
  25. ])
  26. const VERSION_SCHEMA = {
  27. anyOf: [
  28. { enum: Array.from(VERSION_MAP.keys()) },
  29. {
  30. type: "string",
  31. pattern: "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$",
  32. },
  33. ],
  34. }
  35. const DEFAULT_VERSION = "4.0.0"
  36. const FUNC_TYPE = /^(?:Arrow)?Function(?:Declaration|Expression)$/u
  37. const CLASS_TYPE = /^Class(?:Declaration|Expression)$/u
  38. const DESTRUCTURING_PARENT_TYPE =
  39. /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression|AssignmentExpression|VariableDeclarator)$/u
  40. const TOPLEVEL_SCOPE_TYPE = /^(?:global|function|module)$/u
  41. const BINARY_NUMBER = /^0[bB]/u
  42. const OCTAL_NUMBER = /^0[oO]/u
  43. const UNICODE_ESC = /(\\+)u\{[0-9a-fA-F]+?\}/gu
  44. const GET_OR_SET = /^(?:g|s)et$/u
  45. const NEW_BUILTIN_TYPES = [
  46. "Int8Array",
  47. "Uint8Array",
  48. "Uint8ClampedArray",
  49. "Int16Array",
  50. "Uint16Array",
  51. "Int32Array",
  52. "Uint32Array",
  53. "Float32Array",
  54. "Float64Array",
  55. "DataView",
  56. "Map",
  57. "Set",
  58. "WeakMap",
  59. "WeakSet",
  60. "Proxy",
  61. "Reflect",
  62. "Promise",
  63. "Symbol",
  64. "SharedArrayBuffer",
  65. "Atomics",
  66. ]
  67. const SUBCLASSING_TEST_TARGETS = [
  68. "Array",
  69. "RegExp",
  70. "Function",
  71. "Promise",
  72. "Boolean",
  73. "Number",
  74. "String",
  75. "Map",
  76. "Set",
  77. ]
  78. const PROPERTY_TEST_TARGETS = {
  79. Object: [
  80. "assign",
  81. "is",
  82. "getOwnPropertySymbols",
  83. "setPrototypeOf",
  84. "values",
  85. "entries",
  86. "getOwnPropertyDescriptors",
  87. ],
  88. String: ["raw", "fromCodePoint"],
  89. Array: ["from", "of"],
  90. Number: [
  91. "isFinite",
  92. "isInteger",
  93. "isSafeInteger",
  94. "isNaN",
  95. "EPSILON",
  96. "MIN_SAFE_INTEGER",
  97. "MAX_SAFE_INTEGER",
  98. ],
  99. Math: [
  100. "clz32",
  101. "imul",
  102. "sign",
  103. "log10",
  104. "log2",
  105. "log1p",
  106. "expm1",
  107. "cosh",
  108. "sinh",
  109. "tanh",
  110. "acosh",
  111. "asinh",
  112. "atanh",
  113. "trunc",
  114. "fround",
  115. "cbrt",
  116. "hypot",
  117. ],
  118. Symbol: [
  119. "hasInstance",
  120. "isConcatSpreadablec",
  121. "iterator",
  122. "species",
  123. "replace",
  124. "search",
  125. "split",
  126. "match",
  127. "toPrimitive",
  128. "toStringTag",
  129. "unscopables",
  130. ],
  131. Atomics: [
  132. "add",
  133. "and",
  134. "compareExchange",
  135. "exchange",
  136. "wait",
  137. "wake",
  138. "isLockFree",
  139. "load",
  140. "or",
  141. "store",
  142. "sub",
  143. "xor",
  144. ],
  145. }
  146. const REGEXP_NAMED_GROUP = /(\\*)\(\?<[_$\w]/u
  147. const REGEXP_LOOKBEHIND = /(\\*)\(\?<[=!]/u
  148. const REGEXP_UNICODE_PROPERTY = /(\\*)\\[pP]\{.+?\}/u
  149. const FEATURES = {
  150. defaultParameters: {
  151. alias: ["syntax"],
  152. name: "Default parameters",
  153. node: "6.0.0",
  154. },
  155. restParameters: {
  156. alias: ["syntax"],
  157. name: "Rest parameters",
  158. node: "6.0.0",
  159. },
  160. spreadOperators: {
  161. alias: ["syntax"],
  162. name: "Spread operators",
  163. node: "5.0.0",
  164. },
  165. objectLiteralExtensions: {
  166. alias: ["syntax"],
  167. name: "Object literal extensions",
  168. node: "4.0.0",
  169. },
  170. objectPropertyShorthandOfGetSet: {
  171. alias: ["syntax", "objectLiteralExtensions"],
  172. name: "Property shorthand of 'get' and 'set'",
  173. node: "6.0.0",
  174. },
  175. forOf: {
  176. alias: ["syntax"],
  177. name: "'for..of' loops",
  178. node: "0.12.0",
  179. },
  180. binaryNumberLiterals: {
  181. alias: ["syntax"],
  182. name: "Binary number literals",
  183. node: "4.0.0",
  184. },
  185. octalNumberLiterals: {
  186. alias: ["syntax"],
  187. name: "Octal number literals",
  188. node: "4.0.0",
  189. },
  190. templateStrings: {
  191. alias: ["syntax"],
  192. name: "Template strings",
  193. node: "4.0.0",
  194. },
  195. regexpY: {
  196. alias: ["syntax"],
  197. name: "RegExp 'y' flags",
  198. node: "6.0.0",
  199. },
  200. regexpU: {
  201. alias: ["syntax"],
  202. name: "RegExp 'u' flags",
  203. node: "6.0.0",
  204. },
  205. destructuring: {
  206. alias: ["syntax"],
  207. name: "Destructuring",
  208. node: "6.0.0",
  209. },
  210. unicodeCodePointEscapes: {
  211. alias: ["syntax"],
  212. name: "Unicode code point escapes",
  213. node: "4.0.0",
  214. },
  215. "new.target": {
  216. alias: ["syntax"],
  217. name: "'new.target'",
  218. node: "5.0.0",
  219. },
  220. const: {
  221. alias: ["syntax"],
  222. name: "'const' declarations",
  223. node: {
  224. sloppy: "6.0.0",
  225. strict: "4.0.0",
  226. },
  227. },
  228. let: {
  229. alias: ["syntax"],
  230. name: "'let' declarations",
  231. node: {
  232. sloppy: "6.0.0",
  233. strict: "4.0.0",
  234. },
  235. },
  236. blockScopedFunctions: {
  237. alias: ["syntax"],
  238. name: "Block-scoped functions",
  239. node: {
  240. sloppy: "6.0.0",
  241. strict: "4.0.0",
  242. },
  243. },
  244. arrowFunctions: {
  245. alias: ["syntax"],
  246. name: "Arrow functions",
  247. node: "4.0.0",
  248. },
  249. generatorFunctions: {
  250. alias: ["syntax"],
  251. name: "Generator functions",
  252. node: "4.0.0",
  253. },
  254. classes: {
  255. alias: ["syntax"],
  256. name: "Classes",
  257. node: {
  258. sloppy: "6.0.0",
  259. strict: "4.0.0",
  260. },
  261. },
  262. modules: {
  263. alias: ["syntax"],
  264. name: "Import and export declarations",
  265. node: null,
  266. },
  267. exponentialOperators: {
  268. alias: ["syntax"],
  269. name: "Exponential operators (**)",
  270. node: "7.0.0",
  271. },
  272. asyncAwait: {
  273. alias: ["syntax"],
  274. name: "Async functions",
  275. node: "7.6.0",
  276. },
  277. trailingCommasInFunctions: {
  278. alias: ["syntax"],
  279. name: "Trailing commas in functions",
  280. node: "8.0.0",
  281. },
  282. //------------------------------------------
  283. templateLiteralRevision: {
  284. alias: ["syntax"],
  285. name: "Illegal escape sequences in taggled templates",
  286. node: "9.0.0",
  287. },
  288. regexpS: {
  289. alias: ["syntax"],
  290. name: "RegExp 's' flags",
  291. node: "9.0.0",
  292. },
  293. regexpNamedCaptureGroups: {
  294. alias: ["syntax"],
  295. name: "RegExp named capture groups",
  296. node: "10.0.0",
  297. },
  298. regexpLookbehind: {
  299. alias: ["syntax"],
  300. name: "RegExp lookbehind assertions",
  301. node: "9.0.0",
  302. },
  303. regexpUnicodeProperties: {
  304. alias: ["syntax"],
  305. name: "RegExp Unicode property escapes",
  306. node: "10.0.0",
  307. },
  308. restProperties: {
  309. alias: ["syntax"],
  310. name: "Rest properties",
  311. node: "8.3.0",
  312. },
  313. spreadProperties: {
  314. alias: ["syntax"],
  315. name: "Spread properties",
  316. node: "8.3.0",
  317. },
  318. asyncGenerators: {
  319. alias: ["syntax"],
  320. name: "Async generators",
  321. node: "10.0.0",
  322. },
  323. forAwaitOf: {
  324. alias: ["syntax"],
  325. name: "for-await-of loops",
  326. node: "10.0.0",
  327. },
  328. Int8Array: {
  329. alias: ["runtime", "globalObjects", "typedArrays"],
  330. name: "'Int8Array'",
  331. singular: true,
  332. node: "0.12.0",
  333. },
  334. Uint8Array: {
  335. alias: ["runtime", "globalObjects", "typedArrays"],
  336. name: "'Uint8Array'",
  337. singular: true,
  338. node: "0.12.0",
  339. },
  340. Uint8ClampedArray: {
  341. alias: ["runtime", "globalObjects", "typedArrays"],
  342. name: "'Uint8ClampedArray'",
  343. singular: true,
  344. node: "0.12.0",
  345. },
  346. Int16Array: {
  347. alias: ["runtime", "globalObjects", "typedArrays"],
  348. name: "'Int16Array'",
  349. singular: true,
  350. node: "0.12.0",
  351. },
  352. Uint16Array: {
  353. alias: ["runtime", "globalObjects", "typedArrays"],
  354. name: "'Uint16Array'",
  355. singular: true,
  356. node: "0.12.0",
  357. },
  358. Int32Array: {
  359. alias: ["runtime", "globalObjects", "typedArrays"],
  360. name: "'Int32Array'",
  361. singular: true,
  362. node: "0.12.0",
  363. },
  364. Uint32Array: {
  365. alias: ["runtime", "globalObjects", "typedArrays"],
  366. name: "'Uint32Array'",
  367. singular: true,
  368. node: "0.12.0",
  369. },
  370. Float32Array: {
  371. alias: ["runtime", "globalObjects", "typedArrays"],
  372. name: "'Float32Array'",
  373. singular: true,
  374. node: "0.12.0",
  375. },
  376. Float64Array: {
  377. alias: ["runtime", "globalObjects", "typedArrays"],
  378. name: "'Float64Array'",
  379. singular: true,
  380. node: "0.12.0",
  381. },
  382. DataView: {
  383. alias: ["runtime", "globalObjects", "typedArrays"],
  384. name: "'DataView'",
  385. singular: true,
  386. node: "0.12.0",
  387. },
  388. Map: {
  389. alias: ["runtime", "globalObjects"],
  390. name: "'Map'",
  391. singular: true,
  392. node: "0.12.0",
  393. },
  394. Set: {
  395. alias: ["runtime", "globalObjects"],
  396. name: "'Set'",
  397. singular: true,
  398. node: "0.12.0",
  399. },
  400. WeakMap: {
  401. alias: ["runtime", "globalObjects"],
  402. name: "'WeakMap'",
  403. singular: true,
  404. node: "0.12.0",
  405. },
  406. WeakSet: {
  407. alias: ["runtime", "globalObjects"],
  408. name: "'WeakSet'",
  409. singular: true,
  410. node: "0.12.0",
  411. },
  412. Proxy: {
  413. alias: ["runtime", "globalObjects"],
  414. name: "'Proxy'",
  415. singular: true,
  416. node: "6.0.0",
  417. },
  418. Reflect: {
  419. alias: ["runtime", "globalObjects"],
  420. name: "'Reflect'",
  421. singular: true,
  422. node: "6.0.0",
  423. },
  424. Promise: {
  425. alias: ["runtime", "globalObjects"],
  426. name: "'Promise'",
  427. singular: true,
  428. node: "0.12.0",
  429. },
  430. Symbol: {
  431. alias: ["runtime", "globalObjects"],
  432. name: "'Symbol'",
  433. singular: true,
  434. node: "0.12.0",
  435. },
  436. SharedArrayBuffer: {
  437. alias: ["runtime", "globalObjects"],
  438. name: "'SharedArrayBuffer'",
  439. singular: true,
  440. node: "9.0.0",
  441. },
  442. Atomics: {
  443. alias: ["runtime", "globalObjects"],
  444. name: "'Atomics'",
  445. singular: true,
  446. node: "9.0.0",
  447. },
  448. "Object.assign": {
  449. alias: ["runtime", "staticMethods", "Object.*"],
  450. name: "'Object.assign'",
  451. singular: true,
  452. node: "4.0.0",
  453. },
  454. "Object.is": {
  455. alias: ["runtime", "staticMethods", "Object.*"],
  456. name: "'Object.is'",
  457. singular: true,
  458. node: "0.12.0",
  459. },
  460. "Object.getOwnPropertySymbols": {
  461. alias: ["runtime", "staticMethods", "Object.*"],
  462. name: "'Object.getOwnPropertySymbols'",
  463. singular: true,
  464. node: "0.12.0",
  465. },
  466. "Object.setPrototypeOf": {
  467. alias: ["runtime", "staticMethods", "Object.*"],
  468. name: "'Object.setPrototypeOf'",
  469. singular: true,
  470. node: "0.12.0",
  471. },
  472. "Object.values": {
  473. alias: ["runtime", "staticMethods", "Object.*"],
  474. name: "'Object.values'",
  475. singular: true,
  476. node: "7.0.0",
  477. },
  478. "Object.entries": {
  479. alias: ["runtime", "staticMethods", "Object.*"],
  480. name: "'Object.entries'",
  481. singular: true,
  482. node: "7.0.0",
  483. },
  484. "Object.getOwnPropertyDescriptors": {
  485. alias: ["runtime", "staticMethods", "Object.*"],
  486. name: "'Object.getOwnPropertyDescriptors'",
  487. singular: true,
  488. node: "7.0.0",
  489. },
  490. "String.raw": {
  491. alias: ["runtime", "staticMethods", "String.*"],
  492. name: "'String.raw'",
  493. singular: true,
  494. node: "4.0.0",
  495. },
  496. "String.fromCodePoint": {
  497. alias: ["runtime", "staticMethods", "String.*"],
  498. name: "'String.fromCodePoint'",
  499. singular: true,
  500. node: "4.0.0",
  501. },
  502. "Array.from": {
  503. alias: ["runtime", "staticMethods", "Array.*"],
  504. name: "'Array.from'",
  505. singular: true,
  506. node: "4.0.0",
  507. },
  508. "Array.of": {
  509. alias: ["runtime", "staticMethods", "Array.*"],
  510. name: "'Array.of'",
  511. singular: true,
  512. node: "4.0.0",
  513. },
  514. "Number.isFinite": {
  515. alias: ["runtime", "staticMethods", "Number.*"],
  516. name: "'Number.isFinite'",
  517. singular: true,
  518. node: "0.10.0",
  519. },
  520. "Number.isInteger": {
  521. alias: ["runtime", "staticMethods", "Number.*"],
  522. name: "'Number.isInteger'",
  523. singular: true,
  524. node: "0.12.0",
  525. },
  526. "Number.isSafeInteger": {
  527. alias: ["runtime", "staticMethods", "Number.*"],
  528. name: "'Number.isSafeInteger'",
  529. singular: true,
  530. node: "0.12.0",
  531. },
  532. "Number.isNaN": {
  533. alias: ["runtime", "staticMethods", "Number.*"],
  534. name: "'Number.isNaN'",
  535. singular: true,
  536. node: "0.10.0",
  537. },
  538. "Number.EPSILON": {
  539. alias: ["runtime", "staticMethods", "Number.*"],
  540. name: "'Number.EPSILON'",
  541. singular: true,
  542. node: "0.12.0",
  543. },
  544. "Number.MIN_SAFE_INTEGER": {
  545. alias: ["runtime", "staticMethods", "Number.*"],
  546. name: "'Number.MIN_SAFE_INTEGER'",
  547. singular: true,
  548. node: "0.12.0",
  549. },
  550. "Number.MAX_SAFE_INTEGER": {
  551. alias: ["runtime", "staticMethods", "Number.*"],
  552. name: "'Number.MAX_SAFE_INTEGER'",
  553. singular: true,
  554. node: "0.12.0",
  555. },
  556. "Math.clz32": {
  557. alias: ["runtime", "staticMethods", "Math.*"],
  558. name: "'Math.clz32'",
  559. singular: true,
  560. node: "0.12.0",
  561. },
  562. "Math.imul": {
  563. alias: ["runtime", "staticMethods", "Math.*"],
  564. name: "'Math.imul'",
  565. singular: true,
  566. node: "0.12.0",
  567. },
  568. "Math.sign": {
  569. alias: ["runtime", "staticMethods", "Math.*"],
  570. name: "'Math.sign'",
  571. singular: true,
  572. node: "0.12.0",
  573. },
  574. "Math.log10": {
  575. alias: ["runtime", "staticMethods", "Math.*"],
  576. name: "'Math.log10'",
  577. singular: true,
  578. node: "0.12.0",
  579. },
  580. "Math.log2": {
  581. alias: ["runtime", "staticMethods", "Math.*"],
  582. name: "'Math.log2'",
  583. singular: true,
  584. node: "0.12.0",
  585. },
  586. "Math.log1p": {
  587. alias: ["runtime", "staticMethods", "Math.*"],
  588. name: "'Math.log1p'",
  589. singular: true,
  590. node: "0.12.0",
  591. },
  592. "Math.expm1": {
  593. alias: ["runtime", "staticMethods", "Math.*"],
  594. name: "'Math.expm1'",
  595. singular: true,
  596. node: "0.12.0",
  597. },
  598. "Math.cosh": {
  599. alias: ["runtime", "staticMethods", "Math.*"],
  600. name: "'Math.cosh'",
  601. singular: true,
  602. node: "0.12.0",
  603. },
  604. "Math.sinh": {
  605. alias: ["runtime", "staticMethods", "Math.*"],
  606. name: "'Math.sinh'",
  607. singular: true,
  608. node: "0.12.0",
  609. },
  610. "Math.tanh": {
  611. alias: ["runtime", "staticMethods", "Math.*"],
  612. name: "'Math.tanh'",
  613. singular: true,
  614. node: "0.12.0",
  615. },
  616. "Math.acosh": {
  617. alias: ["runtime", "staticMethods", "Math.*"],
  618. name: "'Math.acosh'",
  619. singular: true,
  620. node: "0.12.0",
  621. },
  622. "Math.asinh": {
  623. alias: ["runtime", "staticMethods", "Math.*"],
  624. name: "'Math.asinh'",
  625. singular: true,
  626. node: "0.12.0",
  627. },
  628. "Math.atanh": {
  629. alias: ["runtime", "staticMethods", "Math.*"],
  630. name: "'Math.atanh'",
  631. singular: true,
  632. node: "0.12.0",
  633. },
  634. "Math.trunc": {
  635. alias: ["runtime", "staticMethods", "Math.*"],
  636. name: "'Math.trunc'",
  637. singular: true,
  638. node: "0.12.0",
  639. },
  640. "Math.fround": {
  641. alias: ["runtime", "staticMethods", "Math.*"],
  642. name: "'Math.fround'",
  643. singular: true,
  644. node: "0.12.0",
  645. },
  646. "Math.cbrt": {
  647. alias: ["runtime", "staticMethods", "Math.*"],
  648. name: "'Math.cbrt'",
  649. singular: true,
  650. node: "0.12.0",
  651. },
  652. "Math.hypot": {
  653. alias: ["runtime", "staticMethods", "Math.*"],
  654. name: "'Math.hypot'",
  655. singular: true,
  656. node: "0.12.0",
  657. },
  658. "Symbol.hasInstance": {
  659. alias: ["runtime", "staticMethods", "Symbol.*"],
  660. name: "'Symbol.hasInstance'",
  661. singular: true,
  662. node: "6.5.0",
  663. },
  664. "Symbol.isConcatSpreadablec": {
  665. alias: ["runtime", "staticMethods", "Symbol.*"],
  666. name: "'Symbol.isConcatSpreadablec'",
  667. singular: true,
  668. node: "6.0.0",
  669. },
  670. "Symbol.iterator": {
  671. alias: ["runtime", "staticMethods", "Symbol.*"],
  672. name: "'Symbol.iterator'",
  673. singular: true,
  674. node: "0.12.0",
  675. },
  676. "Symbol.species": {
  677. alias: ["runtime", "staticMethods", "Symbol.*"],
  678. name: "'Symbol.species'",
  679. singular: true,
  680. node: "6.5.0",
  681. },
  682. "Symbol.replace": {
  683. alias: ["runtime", "staticMethods", "Symbol.*"],
  684. name: "'Symbol.replace'",
  685. singular: true,
  686. node: "6.0.0",
  687. },
  688. "Symbol.search": {
  689. alias: ["runtime", "staticMethods", "Symbol.*"],
  690. name: "'Symbol.search'",
  691. singular: true,
  692. node: "6.0.0",
  693. },
  694. "Symbol.split": {
  695. alias: ["runtime", "staticMethods", "Symbol.*"],
  696. name: "'Symbol.split'",
  697. singular: true,
  698. node: "6.0.0",
  699. },
  700. "Symbol.match": {
  701. alias: ["runtime", "staticMethods", "Symbol.*"],
  702. name: "'Symbol.match'",
  703. singular: true,
  704. node: "6.0.0",
  705. },
  706. "Symbol.toPrimitive": {
  707. alias: ["runtime", "staticMethods", "Symbol.*"],
  708. name: "'Symbol.toPrimitive'",
  709. singular: true,
  710. node: "6.0.0",
  711. },
  712. "Symbol.toStringTag": {
  713. alias: ["runtime", "staticMethods", "Symbol.*"],
  714. name: "'Symbol.toStringTag'",
  715. singular: true,
  716. node: "6.0.0",
  717. },
  718. "Symbol.unscopables": {
  719. alias: ["runtime", "staticMethods", "Symbol.*"],
  720. name: "'Symbol.unscopables'",
  721. singular: true,
  722. node: "4.0.0",
  723. },
  724. "Atomics.add": {
  725. alias: ["runtime", "staticMethods", "Atomics.*"],
  726. name: "'Atomics.add'",
  727. singular: true,
  728. node: "9.0.0",
  729. },
  730. "Atomics.and": {
  731. alias: ["runtime", "staticMethods", "Atomics.*"],
  732. name: "'Atomics.and'",
  733. singular: true,
  734. node: "9.0.0",
  735. },
  736. "Atomics.compareExchange": {
  737. alias: ["runtime", "staticMethods", "Atomics.*"],
  738. name: "'Atomics.compareExchange'",
  739. singular: true,
  740. node: "9.0.0",
  741. },
  742. "Atomics.exchange": {
  743. alias: ["runtime", "staticMethods", "Atomics.*"],
  744. name: "'Atomics.exchange'",
  745. singular: true,
  746. node: "9.0.0",
  747. },
  748. "Atomics.wait": {
  749. alias: ["runtime", "staticMethods", "Atomics.*"],
  750. name: "'Atomics.wait'",
  751. singular: true,
  752. node: "9.0.0",
  753. },
  754. "Atomics.wake": {
  755. alias: ["runtime", "staticMethods", "Atomics.*"],
  756. name: "'Atomics.wake'",
  757. singular: true,
  758. node: "9.0.0",
  759. },
  760. "Atomics.isLockFree": {
  761. alias: ["runtime", "staticMethods", "Atomics.*"],
  762. name: "'Atomics.isLockFree'",
  763. singular: true,
  764. node: "9.0.0",
  765. },
  766. "Atomics.load": {
  767. alias: ["runtime", "staticMethods", "Atomics.*"],
  768. name: "'Atomics.load'",
  769. singular: true,
  770. node: "9.0.0",
  771. },
  772. "Atomics.or": {
  773. alias: ["runtime", "staticMethods", "Atomics.*"],
  774. name: "'Atomics.or'",
  775. singular: true,
  776. node: "9.0.0",
  777. },
  778. "Atomics.store": {
  779. alias: ["runtime", "staticMethods", "Atomics.*"],
  780. name: "'Atomics.store'",
  781. singular: true,
  782. node: "9.0.0",
  783. },
  784. "Atomics.sub": {
  785. alias: ["runtime", "staticMethods", "Atomics.*"],
  786. name: "'Atomics.sub'",
  787. singular: true,
  788. node: "9.0.0",
  789. },
  790. "Atomics.xor": {
  791. alias: ["runtime", "staticMethods", "Atomics.*"],
  792. name: "'Atomics.xor'",
  793. singular: true,
  794. node: "9.0.0",
  795. },
  796. extendsArray: {
  797. alias: ["runtime", "extends"],
  798. name: "Subclassing of 'Array'",
  799. singular: true,
  800. node: "6.0.0",
  801. },
  802. extendsRegExp: {
  803. alias: ["runtime", "extends"],
  804. name: "Subclassing of 'RegExp'",
  805. singular: true,
  806. node: "5.0.0",
  807. },
  808. extendsFunction: {
  809. alias: ["runtime", "extends"],
  810. name: "Subclassing of 'Function'",
  811. singular: true,
  812. node: "6.0.0",
  813. },
  814. extendsPromise: {
  815. alias: ["runtime", "extends"],
  816. name: "Subclassing of 'Promise'",
  817. singular: true,
  818. node: "5.0.0",
  819. },
  820. extendsBoolean: {
  821. alias: ["runtime", "extends"],
  822. name: "Subclassing of 'Boolean'",
  823. singular: true,
  824. node: "4.0.0",
  825. },
  826. extendsNumber: {
  827. alias: ["runtime", "extends"],
  828. name: "Subclassing of 'Number'",
  829. singular: true,
  830. node: "4.0.0",
  831. },
  832. extendsString: {
  833. alias: ["runtime", "extends"],
  834. name: "Subclassing of 'String'",
  835. singular: true,
  836. node: "4.0.0",
  837. },
  838. extendsMap: {
  839. alias: ["runtime", "extends"],
  840. name: "Subclassing of 'Map'",
  841. singular: true,
  842. node: "4.0.0",
  843. },
  844. extendsSet: {
  845. alias: ["runtime", "extends"],
  846. name: "Subclassing of 'Set'",
  847. singular: true,
  848. node: "4.0.0",
  849. },
  850. extendsNull: {
  851. alias: ["runtime", "extends"],
  852. name: "'extends null'",
  853. singular: true,
  854. node: null,
  855. },
  856. }
  857. const OPTIONS = Object.keys(FEATURES)
  858. /**
  859. * Gets default version configuration of this rule.
  860. *
  861. * This finds and reads 'package.json' file, then parses 'engines.node' field.
  862. * If it's nothing, this returns null.
  863. *
  864. * @param {string} filename - The file name of the current linting file.
  865. * @returns {string} The default version configuration.
  866. */
  867. function getDefaultVersion(filename) {
  868. const info = getPackageJson(filename)
  869. const nodeVersion = info && info.engines && info.engines.node
  870. return semver.validRange(nodeVersion) || DEFAULT_VERSION
  871. }
  872. /**
  873. * Gets values of the `ignores` option.
  874. *
  875. * @returns {string[]} Values of the `ignores` option.
  876. */
  877. function getIgnoresEnum() {
  878. return Object.keys(
  879. OPTIONS.reduce((retv, key) => {
  880. for (const alias of FEATURES[key].alias) {
  881. retv[alias] = true
  882. }
  883. retv[key] = true
  884. return retv
  885. }, Object.create(null))
  886. )
  887. }
  888. /**
  889. * Checks whether a given key should be ignored or not.
  890. *
  891. * @param {string} key - A key to check.
  892. * @param {string[]} ignores - An array of keys and aliases to be ignored.
  893. * @returns {boolean} `true` if the key should be ignored.
  894. */
  895. function isIgnored(key, ignores) {
  896. return (
  897. ignores.indexOf(key) !== -1 ||
  898. FEATURES[key].alias.some(alias => ignores.indexOf(alias) !== -1)
  899. )
  900. }
  901. /**
  902. * Parses the options.
  903. *
  904. * @param {number|string|object|undefined} options - An option object to parse.
  905. * @param {number} defaultVersion - The default version to use if the version option was omitted.
  906. * @returns {object} Parsed value.
  907. */
  908. function parseOptions(options, defaultVersion) {
  909. let version = null
  910. let range = null
  911. let ignores = []
  912. if (typeof options === "number") {
  913. version = VERSION_MAP.get(options)
  914. } else if (typeof options === "string") {
  915. version = options
  916. } else if (typeof options === "object") {
  917. version =
  918. typeof options.version === "number"
  919. ? VERSION_MAP.get(options.version)
  920. : options.version
  921. ignores = options.ignores || []
  922. }
  923. range = semver.validRange(version ? `>=${version}` : defaultVersion)
  924. if (!version) {
  925. version = defaultVersion
  926. }
  927. return Object.freeze({
  928. version,
  929. features: Object.freeze(
  930. OPTIONS.reduce((retv, key) => {
  931. const feature = FEATURES[key]
  932. if (isIgnored(key, ignores)) {
  933. retv[key] = Object.freeze({
  934. name: feature.name,
  935. singular: Boolean(feature.singular),
  936. supported: true,
  937. supportedInStrict: true,
  938. })
  939. } else if (typeof feature.node === "string") {
  940. retv[key] = Object.freeze({
  941. name: feature.name,
  942. singular: Boolean(feature.singular),
  943. supported: !semver.intersects(
  944. range,
  945. `<${feature.node}`
  946. ),
  947. supportedInStrict: !semver.intersects(
  948. range,
  949. `<${feature.node}`
  950. ),
  951. })
  952. } else {
  953. retv[key] = Object.freeze({
  954. name: feature.name,
  955. singular: Boolean(feature.singular),
  956. supported:
  957. feature.node != null &&
  958. feature.node.sloppy != null &&
  959. !semver.intersects(
  960. range,
  961. `<${feature.node.sloppy}`
  962. ),
  963. supportedInStrict:
  964. feature.node != null &&
  965. feature.node.strict != null &&
  966. !semver.intersects(
  967. range,
  968. `<${feature.node.strict}`
  969. ),
  970. })
  971. }
  972. return retv
  973. }, Object.create(null))
  974. ),
  975. })
  976. }
  977. /**
  978. * Find the scope that a given node belongs to.
  979. * @param {Scope} initialScope The initial scope to find.
  980. * @param {Node} node The AST node.
  981. * @returns {Scope} The scope that the node belongs to.
  982. */
  983. function normalizeScope(initialScope, node) {
  984. let scope = getInnermostScope(initialScope, node)
  985. while (scope && scope.block === node) {
  986. scope = scope.upper
  987. }
  988. return scope
  989. }
  990. /**
  991. * Checks whether the given string has `\u{90ABCDEF}`-like escapes.
  992. *
  993. * @param {string} raw - The string to check.
  994. * @returns {boolean} `true` if the string has Unicode code point escapes.
  995. */
  996. function hasUnicodeCodePointEscape(raw) {
  997. let match = null
  998. UNICODE_ESC.lastIndex = 0
  999. while ((match = UNICODE_ESC.exec(raw)) != null) {
  1000. if (match[1].length % 2 === 1) {
  1001. return true
  1002. }
  1003. }
  1004. return false
  1005. }
  1006. /**
  1007. * Check a given string has a given pattern.
  1008. * @param {string} s A string to check.
  1009. * @param {RegExp} pattern A RegExp object to check.
  1010. * @returns {boolean} `true` if the string has the pattern.
  1011. */
  1012. function hasPattern(s, pattern) {
  1013. const m = pattern.exec(s)
  1014. return m != null && (m[1] || "").length % 2 === 0
  1015. }
  1016. module.exports = {
  1017. meta: {
  1018. docs: {
  1019. description:
  1020. "disallow unsupported ECMAScript features on the specified version",
  1021. category: "Possible Errors",
  1022. recommended: false,
  1023. url: "https://github.com/weiran-zsd/eslint-plugin-node/blob/HEAD/docs/rules/no-unsupported-features.md",
  1024. },
  1025. type: "problem",
  1026. deprecated: true,
  1027. replacedBy: [
  1028. "n/no-unsupported-features/es-syntax",
  1029. "n/no-unsupported-features/es-builtins",
  1030. ],
  1031. fixable: null,
  1032. schema: [
  1033. {
  1034. anyOf: [
  1035. VERSION_SCHEMA.anyOf[0],
  1036. VERSION_SCHEMA.anyOf[1],
  1037. {
  1038. type: "object",
  1039. properties: {
  1040. version: VERSION_SCHEMA,
  1041. ignores: {
  1042. type: "array",
  1043. items: { enum: getIgnoresEnum() },
  1044. uniqueItems: true,
  1045. },
  1046. },
  1047. additionalProperties: false,
  1048. },
  1049. ],
  1050. },
  1051. ],
  1052. messages: {
  1053. unsupported:
  1054. "{{feature}} {{be}} not supported yet on Node {{version}}.",
  1055. },
  1056. },
  1057. create(context) {
  1058. const sourceCode = context.getSourceCode()
  1059. const supportInfo = parseOptions(
  1060. context.options[0],
  1061. getDefaultVersion(context.getFilename())
  1062. )
  1063. /**
  1064. * Gets the references of the specified global variables.
  1065. *
  1066. * @param {string[]} names - Variable names to get.
  1067. * @returns {void}
  1068. */
  1069. function* getReferences(names) {
  1070. const globalScope = context.getScope()
  1071. for (const name of names) {
  1072. const variable = globalScope.set.get(name)
  1073. if (variable && variable.defs.length === 0) {
  1074. yield* variable.references
  1075. }
  1076. }
  1077. }
  1078. /**
  1079. * Checks whether the given function has trailing commas or not.
  1080. *
  1081. * @param {ASTNode} node - The function node to check.
  1082. * @returns {boolean} `true` if the function has trailing commas.
  1083. */
  1084. function hasTrailingCommaForFunction(node) {
  1085. const length = node.params.length
  1086. return (
  1087. length >= 1 &&
  1088. sourceCode.getTokenAfter(node.params[length - 1]).value === ","
  1089. )
  1090. }
  1091. /**
  1092. * Checks whether the given call expression has trailing commas or not.
  1093. *
  1094. * @param {ASTNode} node - The call expression node to check.
  1095. * @returns {boolean} `true` if the call expression has trailing commas.
  1096. */
  1097. function hasTrailingCommaForCall(node) {
  1098. return (
  1099. node.arguments.length >= 1 &&
  1100. sourceCode.getLastToken(node, 1).value === ","
  1101. )
  1102. }
  1103. /**
  1104. * Checks whether the given class extends from null or not.
  1105. *
  1106. * @param {ASTNode} node - The class node to check.
  1107. * @returns {boolean} `true` if the class extends from null.
  1108. */
  1109. function extendsNull(node) {
  1110. return (
  1111. node.superClass != null &&
  1112. node.superClass.type === "Literal" &&
  1113. node.superClass.value === null
  1114. )
  1115. }
  1116. /**
  1117. * Reports a given node if the specified feature is not supported.
  1118. *
  1119. * @param {ASTNode} node - A node to be reported.
  1120. * @param {string} key - A feature name to report.
  1121. * @returns {void}
  1122. */
  1123. function report(node, key) {
  1124. const version = supportInfo.version
  1125. const feature = supportInfo.features[key]
  1126. if (feature.supported) {
  1127. return
  1128. }
  1129. if (!feature.supportedInStrict) {
  1130. context.report({
  1131. node,
  1132. messageId: "unsupported",
  1133. data: {
  1134. feature: feature.name,
  1135. be: feature.singular ? "is" : "are",
  1136. version,
  1137. },
  1138. })
  1139. } else if (!normalizeScope(context.getScope(), node).isStrict) {
  1140. context.report({
  1141. node,
  1142. messageId: "unsupported",
  1143. data: {
  1144. feature: `${feature.name} in non-strict mode`,
  1145. be: feature.singular ? "is" : "are",
  1146. version,
  1147. },
  1148. })
  1149. }
  1150. }
  1151. /**
  1152. * Validate RegExp syntax.
  1153. * @param {string} pattern A RegExp pattern to check.
  1154. * @param {string} flags A RegExp flags to check.
  1155. * @param {ASTNode} node A node to report.
  1156. * @returns {void}
  1157. */
  1158. function validateRegExp(pattern, flags, node) {
  1159. if (typeof pattern === "string") {
  1160. if (hasPattern(pattern, REGEXP_NAMED_GROUP)) {
  1161. report(node, "regexpNamedCaptureGroups")
  1162. }
  1163. if (hasPattern(pattern, REGEXP_LOOKBEHIND)) {
  1164. report(node, "regexpLookbehind")
  1165. }
  1166. if (hasPattern(pattern, REGEXP_UNICODE_PROPERTY)) {
  1167. report(node, "regexpUnicodeProperties")
  1168. }
  1169. }
  1170. if (typeof flags === "string") {
  1171. if (flags.indexOf("y") !== -1) {
  1172. report(node, "regexpY")
  1173. }
  1174. if (flags.indexOf("u") !== -1) {
  1175. report(node, "regexpU")
  1176. }
  1177. if (flags.indexOf("s") !== -1) {
  1178. report(node, "regexpS")
  1179. }
  1180. }
  1181. }
  1182. /**
  1183. * Validate RegExp syntax in a RegExp literal.
  1184. * @param {ASTNode} node A Literal node to check.
  1185. * @returns {void}
  1186. */
  1187. function validateRegExpLiteral(node) {
  1188. validateRegExp(node.regex.pattern, node.regex.flags, node)
  1189. }
  1190. /**
  1191. * Validate RegExp syntax in the first argument of `new RegExp()`.
  1192. * @param {ASTNode} node A NewExpression node to check.
  1193. * @returns {void}
  1194. */
  1195. function validateRegExpString(node) {
  1196. const patternNode = node.arguments[0]
  1197. const flagsNode = node.arguments[1]
  1198. const pattern =
  1199. patternNode &&
  1200. patternNode.type === "Literal" &&
  1201. typeof patternNode.value === "string"
  1202. ? patternNode.value
  1203. : null
  1204. const flags =
  1205. flagsNode &&
  1206. flagsNode.type === "Literal" &&
  1207. typeof flagsNode.value === "string"
  1208. ? flagsNode.value
  1209. : null
  1210. validateRegExp(pattern, flags, node)
  1211. }
  1212. return {
  1213. "Program:exit"() {
  1214. // Check new global variables.
  1215. for (const name of NEW_BUILTIN_TYPES) {
  1216. for (const reference of getReferences([name])) {
  1217. // Ignore if it's using new static methods.
  1218. const node = reference.identifier
  1219. const parentNode = node.parent
  1220. const properties = PROPERTY_TEST_TARGETS[name]
  1221. if (
  1222. properties &&
  1223. parentNode.type === "MemberExpression"
  1224. ) {
  1225. const propertyName = getPropertyName(parentNode)
  1226. if (properties.indexOf(propertyName) !== -1) {
  1227. continue
  1228. }
  1229. }
  1230. report(reference.identifier, name)
  1231. }
  1232. }
  1233. // Check static methods.
  1234. for (const reference of getReferences(
  1235. Object.keys(PROPERTY_TEST_TARGETS)
  1236. )) {
  1237. const node = reference.identifier
  1238. const parentNode = node.parent
  1239. if (
  1240. parentNode.type !== "MemberExpression" ||
  1241. parentNode.object !== node
  1242. ) {
  1243. continue
  1244. }
  1245. const objectName = node.name
  1246. const properties = PROPERTY_TEST_TARGETS[objectName]
  1247. const propertyName = getPropertyName(parentNode)
  1248. if (
  1249. propertyName &&
  1250. properties.indexOf(propertyName) !== -1
  1251. ) {
  1252. report(parentNode, `${objectName}.${propertyName}`)
  1253. }
  1254. }
  1255. // Check subclassing
  1256. for (const reference of getReferences(
  1257. SUBCLASSING_TEST_TARGETS
  1258. )) {
  1259. const node = reference.identifier
  1260. const parentNode = node.parent
  1261. if (
  1262. CLASS_TYPE.test(parentNode.type) &&
  1263. parentNode.superClass === node
  1264. ) {
  1265. report(node, `extends${node.name}`)
  1266. }
  1267. }
  1268. },
  1269. ArrowFunctionExpression(node) {
  1270. report(node, "arrowFunctions")
  1271. if (node.async) {
  1272. report(node, "asyncAwait")
  1273. }
  1274. if (hasTrailingCommaForFunction(node)) {
  1275. report(node, "trailingCommasInFunctions")
  1276. }
  1277. },
  1278. AssignmentPattern(node) {
  1279. if (FUNC_TYPE.test(node.parent.type)) {
  1280. report(node, "defaultParameters")
  1281. }
  1282. },
  1283. FunctionDeclaration(node) {
  1284. const scope = context.getScope().upper
  1285. if (!TOPLEVEL_SCOPE_TYPE.test(scope.type)) {
  1286. report(node, "blockScopedFunctions")
  1287. }
  1288. if (node.generator) {
  1289. report(node, "generatorFunctions")
  1290. }
  1291. if (node.async) {
  1292. report(node, "asyncAwait")
  1293. }
  1294. if (hasTrailingCommaForFunction(node)) {
  1295. report(node, "trailingCommasInFunctions")
  1296. }
  1297. if (node.async && node.generator) {
  1298. report(node, "asyncGenerators")
  1299. }
  1300. },
  1301. FunctionExpression(node) {
  1302. if (node.generator) {
  1303. report(node, "generatorFunctions")
  1304. }
  1305. if (node.async) {
  1306. report(node, "asyncAwait")
  1307. }
  1308. if (hasTrailingCommaForFunction(node)) {
  1309. report(node, "trailingCommasInFunctions")
  1310. }
  1311. if (node.async && node.generator) {
  1312. report(node, "asyncGenerators")
  1313. }
  1314. },
  1315. MetaProperty(node) {
  1316. const meta = node.meta.name || node.meta
  1317. const property = node.property.name || node.property
  1318. if (meta === "new" && property === "target") {
  1319. report(node, "new.target")
  1320. }
  1321. },
  1322. ClassDeclaration(node) {
  1323. report(node, "classes")
  1324. if (extendsNull(node)) {
  1325. report(node, "extendsNull")
  1326. }
  1327. },
  1328. ClassExpression(node) {
  1329. report(node, "classes")
  1330. if (extendsNull(node)) {
  1331. report(node, "extendsNull")
  1332. }
  1333. },
  1334. ForOfStatement(node) {
  1335. report(node, "forOf")
  1336. if (node.await) {
  1337. report(node, "forAwaitOf")
  1338. }
  1339. },
  1340. VariableDeclaration(node) {
  1341. if (node.kind === "const") {
  1342. report(node, "const")
  1343. } else if (node.kind === "let") {
  1344. report(node, "let")
  1345. }
  1346. },
  1347. ArrayPattern(node) {
  1348. if (DESTRUCTURING_PARENT_TYPE.test(node.parent.type)) {
  1349. report(node, "destructuring")
  1350. }
  1351. },
  1352. AssignmentExpression(node) {
  1353. if (node.operator === "**=") {
  1354. report(node, "exponentialOperators")
  1355. }
  1356. },
  1357. AwaitExpression(node) {
  1358. report(node, "asyncAwait")
  1359. },
  1360. BinaryExpression(node) {
  1361. if (node.operator === "**") {
  1362. report(node, "exponentialOperators")
  1363. }
  1364. },
  1365. CallExpression(node) {
  1366. if (hasTrailingCommaForCall(node)) {
  1367. report(node, "trailingCommasInFunctions")
  1368. }
  1369. },
  1370. Identifier(node) {
  1371. const raw = sourceCode.getText(node)
  1372. if (hasUnicodeCodePointEscape(raw)) {
  1373. report(node, "unicodeCodePointEscapes")
  1374. }
  1375. },
  1376. Literal(node) {
  1377. if (typeof node.value === "number") {
  1378. if (BINARY_NUMBER.test(node.raw)) {
  1379. report(node, "binaryNumberLiterals")
  1380. } else if (OCTAL_NUMBER.test(node.raw)) {
  1381. report(node, "octalNumberLiterals")
  1382. }
  1383. } else if (typeof node.value === "string") {
  1384. if (hasUnicodeCodePointEscape(node.raw)) {
  1385. report(node, "unicodeCodePointEscapes")
  1386. }
  1387. } else if (node.regex) {
  1388. validateRegExpLiteral(node)
  1389. }
  1390. },
  1391. NewExpression(node) {
  1392. if (
  1393. node.callee.type === "Identifier" &&
  1394. node.callee.name === "RegExp"
  1395. ) {
  1396. validateRegExpString(node)
  1397. }
  1398. if (hasTrailingCommaForCall(node)) {
  1399. report(node, "trailingCommasInFunctions")
  1400. }
  1401. },
  1402. ObjectPattern(node) {
  1403. if (DESTRUCTURING_PARENT_TYPE.test(node.parent.type)) {
  1404. report(node, "destructuring")
  1405. }
  1406. },
  1407. Property(node) {
  1408. if (
  1409. node.parent.type === "ObjectExpression" &&
  1410. (node.computed || node.shorthand || node.method)
  1411. ) {
  1412. if (node.shorthand && GET_OR_SET.test(node.key.name)) {
  1413. report(node, "objectPropertyShorthandOfGetSet")
  1414. } else {
  1415. report(node, "objectLiteralExtensions")
  1416. }
  1417. }
  1418. },
  1419. RestElement(node) {
  1420. if (FUNC_TYPE.test(node.parent.type)) {
  1421. report(node, "restParameters")
  1422. } else if (node.parent.type === "ObjectPattern") {
  1423. report(node, "restProperties")
  1424. }
  1425. },
  1426. SpreadElement(node) {
  1427. if (node.parent.type === "ObjectExpression") {
  1428. report(node, "spreadProperties")
  1429. } else {
  1430. report(node, "spreadOperators")
  1431. }
  1432. },
  1433. TemplateElement(node) {
  1434. if (node.value.cooked == null) {
  1435. report(node, "templateLiteralRevision")
  1436. }
  1437. },
  1438. TemplateLiteral(node) {
  1439. report(node, "templateStrings")
  1440. },
  1441. ExperimentalRestProperty(node) {
  1442. report(node, "restProperties")
  1443. },
  1444. ExperimentalSpreadProperty(node) {
  1445. report(node, "spreadProperties")
  1446. },
  1447. RestProperty(node) {
  1448. report(node, "restProperties")
  1449. },
  1450. SpreadProperty(node) {
  1451. report(node, "spreadProperties")
  1452. },
  1453. ExportAllDeclaration(node) {
  1454. report(node, "modules")
  1455. },
  1456. ExportDefaultDeclaration(node) {
  1457. report(node, "modules")
  1458. },
  1459. ExportNamedDeclaration(node) {
  1460. report(node, "modules")
  1461. },
  1462. ImportDeclaration(node) {
  1463. report(node, "modules")
  1464. },
  1465. }
  1466. },
  1467. }