no-unsupported-features.js 43 KB

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