eslint-scope.cjs 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var estraverse = require('estraverse');
  4. var esrecurse = require('esrecurse');
  5. function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  6. var estraverse__default = /*#__PURE__*/_interopDefaultLegacy(estraverse);
  7. var esrecurse__default = /*#__PURE__*/_interopDefaultLegacy(esrecurse);
  8. /**
  9. * @fileoverview Assertion utilities.
  10. * @author Nicholas C. Zakas
  11. */
  12. /**
  13. * Throws an error if the given condition is not truthy.
  14. * @param {boolean} condition The condition to check.
  15. * @param {string} message The message to include with the error.
  16. * @returns {void}
  17. * @throws {Error} When the condition is not truthy.
  18. */
  19. function assert(condition, message = "Assertion failed.") {
  20. if (!condition) {
  21. throw new Error(message);
  22. }
  23. }
  24. /*
  25. Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
  26. Redistribution and use in source and binary forms, with or without
  27. modification, are permitted provided that the following conditions are met:
  28. * Redistributions of source code must retain the above copyright
  29. notice, this list of conditions and the following disclaimer.
  30. * Redistributions in binary form must reproduce the above copyright
  31. notice, this list of conditions and the following disclaimer in the
  32. documentation and/or other materials provided with the distribution.
  33. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  34. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  35. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  36. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  37. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  40. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  42. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43. */
  44. const READ = 0x1;
  45. const WRITE = 0x2;
  46. const RW = READ | WRITE;
  47. /**
  48. * A Reference represents a single occurrence of an identifier in code.
  49. * @constructor Reference
  50. */
  51. class Reference {
  52. constructor(ident, scope, flag, writeExpr, maybeImplicitGlobal, partial, init) {
  53. /**
  54. * Identifier syntax node.
  55. * @member {espreeIdentifier} Reference#identifier
  56. */
  57. this.identifier = ident;
  58. /**
  59. * Reference to the enclosing Scope.
  60. * @member {Scope} Reference#from
  61. */
  62. this.from = scope;
  63. /**
  64. * Whether the reference comes from a dynamic scope (such as 'eval',
  65. * 'with', etc.), and may be trapped by dynamic scopes.
  66. * @member {boolean} Reference#tainted
  67. */
  68. this.tainted = false;
  69. /**
  70. * The variable this reference is resolved with.
  71. * @member {Variable} Reference#resolved
  72. */
  73. this.resolved = null;
  74. /**
  75. * The read-write mode of the reference. (Value is one of {@link
  76. * Reference.READ}, {@link Reference.RW}, {@link Reference.WRITE}).
  77. * @member {number} Reference#flag
  78. * @private
  79. */
  80. this.flag = flag;
  81. if (this.isWrite()) {
  82. /**
  83. * If reference is writeable, this is the tree being written to it.
  84. * @member {espreeNode} Reference#writeExpr
  85. */
  86. this.writeExpr = writeExpr;
  87. /**
  88. * Whether the Reference might refer to a partial value of writeExpr.
  89. * @member {boolean} Reference#partial
  90. */
  91. this.partial = partial;
  92. /**
  93. * Whether the Reference is to write of initialization.
  94. * @member {boolean} Reference#init
  95. */
  96. this.init = init;
  97. }
  98. this.__maybeImplicitGlobal = maybeImplicitGlobal;
  99. }
  100. /**
  101. * Whether the reference is static.
  102. * @function Reference#isStatic
  103. * @returns {boolean} static
  104. */
  105. isStatic() {
  106. return !this.tainted && this.resolved && this.resolved.scope.isStatic();
  107. }
  108. /**
  109. * Whether the reference is writeable.
  110. * @function Reference#isWrite
  111. * @returns {boolean} write
  112. */
  113. isWrite() {
  114. return !!(this.flag & Reference.WRITE);
  115. }
  116. /**
  117. * Whether the reference is readable.
  118. * @function Reference#isRead
  119. * @returns {boolean} read
  120. */
  121. isRead() {
  122. return !!(this.flag & Reference.READ);
  123. }
  124. /**
  125. * Whether the reference is read-only.
  126. * @function Reference#isReadOnly
  127. * @returns {boolean} read only
  128. */
  129. isReadOnly() {
  130. return this.flag === Reference.READ;
  131. }
  132. /**
  133. * Whether the reference is write-only.
  134. * @function Reference#isWriteOnly
  135. * @returns {boolean} write only
  136. */
  137. isWriteOnly() {
  138. return this.flag === Reference.WRITE;
  139. }
  140. /**
  141. * Whether the reference is read-write.
  142. * @function Reference#isReadWrite
  143. * @returns {boolean} read write
  144. */
  145. isReadWrite() {
  146. return this.flag === Reference.RW;
  147. }
  148. }
  149. /**
  150. * @constant Reference.READ
  151. * @private
  152. */
  153. Reference.READ = READ;
  154. /**
  155. * @constant Reference.WRITE
  156. * @private
  157. */
  158. Reference.WRITE = WRITE;
  159. /**
  160. * @constant Reference.RW
  161. * @private
  162. */
  163. Reference.RW = RW;
  164. /* vim: set sw=4 ts=4 et tw=80 : */
  165. /*
  166. Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
  167. Redistribution and use in source and binary forms, with or without
  168. modification, are permitted provided that the following conditions are met:
  169. * Redistributions of source code must retain the above copyright
  170. notice, this list of conditions and the following disclaimer.
  171. * Redistributions in binary form must reproduce the above copyright
  172. notice, this list of conditions and the following disclaimer in the
  173. documentation and/or other materials provided with the distribution.
  174. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  175. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  176. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  177. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  178. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  179. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  180. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  181. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  182. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  183. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  184. */
  185. /**
  186. * A Variable represents a locally scoped identifier. These include arguments to
  187. * functions.
  188. * @constructor Variable
  189. */
  190. class Variable {
  191. constructor(name, scope) {
  192. /**
  193. * The variable name, as given in the source code.
  194. * @member {string} Variable#name
  195. */
  196. this.name = name;
  197. /**
  198. * List of defining occurrences of this variable (like in 'var ...'
  199. * statements or as parameter), as AST nodes.
  200. * @member {espree.Identifier[]} Variable#identifiers
  201. */
  202. this.identifiers = [];
  203. /**
  204. * List of {@link Reference|references} of this variable (excluding parameter entries)
  205. * in its defining scope and all nested scopes. For defining
  206. * occurrences only see {@link Variable#defs}.
  207. * @member {Reference[]} Variable#references
  208. */
  209. this.references = [];
  210. /**
  211. * List of defining occurrences of this variable (like in 'var ...'
  212. * statements or as parameter), as custom objects.
  213. * @member {Definition[]} Variable#defs
  214. */
  215. this.defs = [];
  216. this.tainted = false;
  217. /**
  218. * Whether this is a stack variable.
  219. * @member {boolean} Variable#stack
  220. */
  221. this.stack = true;
  222. /**
  223. * Reference to the enclosing Scope.
  224. * @member {Scope} Variable#scope
  225. */
  226. this.scope = scope;
  227. }
  228. }
  229. Variable.CatchClause = "CatchClause";
  230. Variable.Parameter = "Parameter";
  231. Variable.FunctionName = "FunctionName";
  232. Variable.ClassName = "ClassName";
  233. Variable.Variable = "Variable";
  234. Variable.ImportBinding = "ImportBinding";
  235. Variable.ImplicitGlobalVariable = "ImplicitGlobalVariable";
  236. /* vim: set sw=4 ts=4 et tw=80 : */
  237. /*
  238. Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
  239. Redistribution and use in source and binary forms, with or without
  240. modification, are permitted provided that the following conditions are met:
  241. * Redistributions of source code must retain the above copyright
  242. notice, this list of conditions and the following disclaimer.
  243. * Redistributions in binary form must reproduce the above copyright
  244. notice, this list of conditions and the following disclaimer in the
  245. documentation and/or other materials provided with the distribution.
  246. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  247. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  248. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  249. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  250. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  251. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  252. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  253. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  254. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  255. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  256. */
  257. /**
  258. * @constructor Definition
  259. */
  260. class Definition {
  261. constructor(type, name, node, parent, index, kind) {
  262. /**
  263. * @member {string} Definition#type - type of the occurrence (e.g. "Parameter", "Variable", ...).
  264. */
  265. this.type = type;
  266. /**
  267. * @member {espree.Identifier} Definition#name - the identifier AST node of the occurrence.
  268. */
  269. this.name = name;
  270. /**
  271. * @member {espree.Node} Definition#node - the enclosing node of the identifier.
  272. */
  273. this.node = node;
  274. /**
  275. * @member {espree.Node?} Definition#parent - the enclosing statement node of the identifier.
  276. */
  277. this.parent = parent;
  278. /**
  279. * @member {number?} Definition#index - the index in the declaration statement.
  280. */
  281. this.index = index;
  282. /**
  283. * @member {string?} Definition#kind - the kind of the declaration statement.
  284. */
  285. this.kind = kind;
  286. }
  287. }
  288. /**
  289. * @constructor ParameterDefinition
  290. */
  291. class ParameterDefinition extends Definition {
  292. constructor(name, node, index, rest) {
  293. super(Variable.Parameter, name, node, null, index, null);
  294. /**
  295. * Whether the parameter definition is a part of a rest parameter.
  296. * @member {boolean} ParameterDefinition#rest
  297. */
  298. this.rest = rest;
  299. }
  300. }
  301. /* vim: set sw=4 ts=4 et tw=80 : */
  302. /*
  303. Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
  304. Redistribution and use in source and binary forms, with or without
  305. modification, are permitted provided that the following conditions are met:
  306. * Redistributions of source code must retain the above copyright
  307. notice, this list of conditions and the following disclaimer.
  308. * Redistributions in binary form must reproduce the above copyright
  309. notice, this list of conditions and the following disclaimer in the
  310. documentation and/or other materials provided with the distribution.
  311. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  312. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  313. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  314. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  315. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  316. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  317. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  318. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  319. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  320. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  321. */
  322. const { Syntax: Syntax$2 } = estraverse__default["default"];
  323. /**
  324. * Test if scope is struct
  325. * @param {Scope} scope scope
  326. * @param {Block} block block
  327. * @param {boolean} isMethodDefinition is method definition
  328. * @returns {boolean} is strict scope
  329. */
  330. function isStrictScope(scope, block, isMethodDefinition) {
  331. let body;
  332. // When upper scope is exists and strict, inner scope is also strict.
  333. if (scope.upper && scope.upper.isStrict) {
  334. return true;
  335. }
  336. if (isMethodDefinition) {
  337. return true;
  338. }
  339. if (scope.type === "class" || scope.type === "module") {
  340. return true;
  341. }
  342. if (scope.type === "block" || scope.type === "switch") {
  343. return false;
  344. }
  345. if (scope.type === "function") {
  346. if (block.type === Syntax$2.ArrowFunctionExpression && block.body.type !== Syntax$2.BlockStatement) {
  347. return false;
  348. }
  349. if (block.type === Syntax$2.Program) {
  350. body = block;
  351. } else {
  352. body = block.body;
  353. }
  354. if (!body) {
  355. return false;
  356. }
  357. } else if (scope.type === "global") {
  358. body = block;
  359. } else {
  360. return false;
  361. }
  362. // Search for a 'use strict' directive.
  363. for (let i = 0, iz = body.body.length; i < iz; ++i) {
  364. const stmt = body.body[i];
  365. /*
  366. * Check if the current statement is a directive.
  367. * If it isn't, then we're past the directive prologue
  368. * so stop the search because directives cannot
  369. * appear after this point.
  370. *
  371. * Some parsers set `directive:null` on non-directive
  372. * statements, so the `typeof` check is safer than
  373. * checking for property existence.
  374. */
  375. if (typeof stmt.directive !== "string") {
  376. break;
  377. }
  378. if (stmt.directive === "use strict") {
  379. return true;
  380. }
  381. }
  382. return false;
  383. }
  384. /**
  385. * Register scope
  386. * @param {ScopeManager} scopeManager scope manager
  387. * @param {Scope} scope scope
  388. * @returns {void}
  389. */
  390. function registerScope(scopeManager, scope) {
  391. scopeManager.scopes.push(scope);
  392. const scopes = scopeManager.__nodeToScope.get(scope.block);
  393. if (scopes) {
  394. scopes.push(scope);
  395. } else {
  396. scopeManager.__nodeToScope.set(scope.block, [scope]);
  397. }
  398. }
  399. /**
  400. * Should be statically
  401. * @param {Object} def def
  402. * @returns {boolean} should be statically
  403. */
  404. function shouldBeStatically(def) {
  405. return (
  406. (def.type === Variable.ClassName) ||
  407. (def.type === Variable.Variable && def.parent.kind !== "var")
  408. );
  409. }
  410. /**
  411. * @constructor Scope
  412. */
  413. class Scope {
  414. constructor(scopeManager, type, upperScope, block, isMethodDefinition) {
  415. /**
  416. * One of "global", "module", "function", "function-expression-name", "block", "switch", "catch", "with", "for",
  417. * "class", "class-field-initializer", "class-static-block".
  418. * @member {string} Scope#type
  419. */
  420. this.type = type;
  421. /**
  422. * The scoped {@link Variable}s of this scope, as <code>{ Variable.name
  423. * : Variable }</code>.
  424. * @member {Map} Scope#set
  425. */
  426. this.set = new Map();
  427. /**
  428. * The tainted variables of this scope, as <code>{ Variable.name :
  429. * boolean }</code>.
  430. * @member {Map} Scope#taints
  431. */
  432. this.taints = new Map();
  433. /**
  434. * Generally, through the lexical scoping of JS you can always know
  435. * which variable an identifier in the source code refers to. There are
  436. * a few exceptions to this rule. With 'global' and 'with' scopes you
  437. * can only decide at runtime which variable a reference refers to.
  438. * Moreover, if 'eval()' is used in a scope, it might introduce new
  439. * bindings in this or its parent scopes.
  440. * All those scopes are considered 'dynamic'.
  441. * @member {boolean} Scope#dynamic
  442. */
  443. this.dynamic = this.type === "global" || this.type === "with";
  444. /**
  445. * A reference to the scope-defining syntax node.
  446. * @member {espree.Node} Scope#block
  447. */
  448. this.block = block;
  449. /**
  450. * The {@link Reference|references} that are not resolved with this scope.
  451. * @member {Reference[]} Scope#through
  452. */
  453. this.through = [];
  454. /**
  455. * The scoped {@link Variable}s of this scope. In the case of a
  456. * 'function' scope this includes the automatic argument <em>arguments</em> as
  457. * its first element, as well as all further formal arguments.
  458. * @member {Variable[]} Scope#variables
  459. */
  460. this.variables = [];
  461. /**
  462. * Any variable {@link Reference|reference} found in this scope. This
  463. * includes occurrences of local variables as well as variables from
  464. * parent scopes (including the global scope). For local variables
  465. * this also includes defining occurrences (like in a 'var' statement).
  466. * In a 'function' scope this does not include the occurrences of the
  467. * formal parameter in the parameter list.
  468. * @member {Reference[]} Scope#references
  469. */
  470. this.references = [];
  471. /**
  472. * For 'global' and 'function' scopes, this is a self-reference. For
  473. * other scope types this is the <em>variableScope</em> value of the
  474. * parent scope.
  475. * @member {Scope} Scope#variableScope
  476. */
  477. this.variableScope =
  478. this.type === "global" ||
  479. this.type === "module" ||
  480. this.type === "function" ||
  481. this.type === "class-field-initializer" ||
  482. this.type === "class-static-block"
  483. ? this
  484. : upperScope.variableScope;
  485. /**
  486. * Whether this scope is created by a FunctionExpression.
  487. * @member {boolean} Scope#functionExpressionScope
  488. */
  489. this.functionExpressionScope = false;
  490. /**
  491. * Whether this is a scope that contains an 'eval()' invocation.
  492. * @member {boolean} Scope#directCallToEvalScope
  493. */
  494. this.directCallToEvalScope = false;
  495. /**
  496. * @member {boolean} Scope#thisFound
  497. */
  498. this.thisFound = false;
  499. this.__left = [];
  500. /**
  501. * Reference to the parent {@link Scope|scope}.
  502. * @member {Scope} Scope#upper
  503. */
  504. this.upper = upperScope;
  505. /**
  506. * Whether 'use strict' is in effect in this scope.
  507. * @member {boolean} Scope#isStrict
  508. */
  509. this.isStrict = scopeManager.isStrictModeSupported()
  510. ? isStrictScope(this, block, isMethodDefinition)
  511. : false;
  512. /**
  513. * List of nested {@link Scope}s.
  514. * @member {Scope[]} Scope#childScopes
  515. */
  516. this.childScopes = [];
  517. if (this.upper) {
  518. this.upper.childScopes.push(this);
  519. }
  520. this.__declaredVariables = scopeManager.__declaredVariables;
  521. registerScope(scopeManager, this);
  522. }
  523. __shouldStaticallyClose(scopeManager) {
  524. return (!this.dynamic || scopeManager.__isOptimistic());
  525. }
  526. __shouldStaticallyCloseForGlobal(ref) {
  527. // On global scope, let/const/class declarations should be resolved statically.
  528. const name = ref.identifier.name;
  529. if (!this.set.has(name)) {
  530. return false;
  531. }
  532. const variable = this.set.get(name);
  533. const defs = variable.defs;
  534. return defs.length > 0 && defs.every(shouldBeStatically);
  535. }
  536. __staticCloseRef(ref) {
  537. if (!this.__resolve(ref)) {
  538. this.__delegateToUpperScope(ref);
  539. }
  540. }
  541. __dynamicCloseRef(ref) {
  542. // notify all names are through to global
  543. let current = this;
  544. do {
  545. current.through.push(ref);
  546. current = current.upper;
  547. } while (current);
  548. }
  549. __globalCloseRef(ref) {
  550. // let/const/class declarations should be resolved statically.
  551. // others should be resolved dynamically.
  552. if (this.__shouldStaticallyCloseForGlobal(ref)) {
  553. this.__staticCloseRef(ref);
  554. } else {
  555. this.__dynamicCloseRef(ref);
  556. }
  557. }
  558. __close(scopeManager) {
  559. let closeRef;
  560. if (this.__shouldStaticallyClose(scopeManager)) {
  561. closeRef = this.__staticCloseRef;
  562. } else if (this.type !== "global") {
  563. closeRef = this.__dynamicCloseRef;
  564. } else {
  565. closeRef = this.__globalCloseRef;
  566. }
  567. // Try Resolving all references in this scope.
  568. for (let i = 0, iz = this.__left.length; i < iz; ++i) {
  569. const ref = this.__left[i];
  570. closeRef.call(this, ref);
  571. }
  572. this.__left = null;
  573. return this.upper;
  574. }
  575. // To override by function scopes.
  576. // References in default parameters isn't resolved to variables which are in their function body.
  577. __isValidResolution(ref, variable) { // eslint-disable-line class-methods-use-this, no-unused-vars -- Desired as instance method with signature
  578. return true;
  579. }
  580. __resolve(ref) {
  581. const name = ref.identifier.name;
  582. if (!this.set.has(name)) {
  583. return false;
  584. }
  585. const variable = this.set.get(name);
  586. if (!this.__isValidResolution(ref, variable)) {
  587. return false;
  588. }
  589. variable.references.push(ref);
  590. variable.stack = variable.stack && ref.from.variableScope === this.variableScope;
  591. if (ref.tainted) {
  592. variable.tainted = true;
  593. this.taints.set(variable.name, true);
  594. }
  595. ref.resolved = variable;
  596. return true;
  597. }
  598. __delegateToUpperScope(ref) {
  599. if (this.upper) {
  600. this.upper.__left.push(ref);
  601. }
  602. this.through.push(ref);
  603. }
  604. __addDeclaredVariablesOfNode(variable, node) {
  605. if (node === null || node === void 0) {
  606. return;
  607. }
  608. let variables = this.__declaredVariables.get(node);
  609. if (variables === null || variables === void 0) {
  610. variables = [];
  611. this.__declaredVariables.set(node, variables);
  612. }
  613. if (!variables.includes(variable)) {
  614. variables.push(variable);
  615. }
  616. }
  617. __defineGeneric(name, set, variables, node, def) {
  618. let variable;
  619. variable = set.get(name);
  620. if (!variable) {
  621. variable = new Variable(name, this);
  622. set.set(name, variable);
  623. variables.push(variable);
  624. }
  625. if (def) {
  626. variable.defs.push(def);
  627. this.__addDeclaredVariablesOfNode(variable, def.node);
  628. this.__addDeclaredVariablesOfNode(variable, def.parent);
  629. }
  630. if (node) {
  631. variable.identifiers.push(node);
  632. }
  633. }
  634. __define(node, def) {
  635. if (node && node.type === Syntax$2.Identifier) {
  636. this.__defineGeneric(
  637. node.name,
  638. this.set,
  639. this.variables,
  640. node,
  641. def
  642. );
  643. }
  644. }
  645. __referencing(node, assign, writeExpr, maybeImplicitGlobal, partial, init) {
  646. // because Array element may be null
  647. if (!node || node.type !== Syntax$2.Identifier) {
  648. return;
  649. }
  650. // Specially handle like `this`.
  651. if (node.name === "super") {
  652. return;
  653. }
  654. const ref = new Reference(node, this, assign || Reference.READ, writeExpr, maybeImplicitGlobal, !!partial, !!init);
  655. this.references.push(ref);
  656. this.__left.push(ref);
  657. }
  658. __detectEval() {
  659. let current = this;
  660. this.directCallToEvalScope = true;
  661. do {
  662. current.dynamic = true;
  663. current = current.upper;
  664. } while (current);
  665. }
  666. __detectThis() {
  667. this.thisFound = true;
  668. }
  669. __isClosed() {
  670. return this.__left === null;
  671. }
  672. /**
  673. * returns resolved {Reference}
  674. * @function Scope#resolve
  675. * @param {Espree.Identifier} ident identifier to be resolved.
  676. * @returns {Reference} reference
  677. */
  678. resolve(ident) {
  679. let ref, i, iz;
  680. assert(this.__isClosed(), "Scope should be closed.");
  681. assert(ident.type === Syntax$2.Identifier, "Target should be identifier.");
  682. for (i = 0, iz = this.references.length; i < iz; ++i) {
  683. ref = this.references[i];
  684. if (ref.identifier === ident) {
  685. return ref;
  686. }
  687. }
  688. return null;
  689. }
  690. /**
  691. * returns this scope is static
  692. * @function Scope#isStatic
  693. * @returns {boolean} static
  694. */
  695. isStatic() {
  696. return !this.dynamic;
  697. }
  698. /**
  699. * returns this scope has materialized arguments
  700. * @function Scope#isArgumentsMaterialized
  701. * @returns {boolean} arguemnts materialized
  702. */
  703. isArgumentsMaterialized() { // eslint-disable-line class-methods-use-this -- Desired as instance method
  704. return true;
  705. }
  706. /**
  707. * returns this scope has materialized `this` reference
  708. * @function Scope#isThisMaterialized
  709. * @returns {boolean} this materialized
  710. */
  711. isThisMaterialized() { // eslint-disable-line class-methods-use-this -- Desired as instance method
  712. return true;
  713. }
  714. isUsedName(name) {
  715. if (this.set.has(name)) {
  716. return true;
  717. }
  718. for (let i = 0, iz = this.through.length; i < iz; ++i) {
  719. if (this.through[i].identifier.name === name) {
  720. return true;
  721. }
  722. }
  723. return false;
  724. }
  725. }
  726. /**
  727. * Global scope.
  728. */
  729. class GlobalScope extends Scope {
  730. constructor(scopeManager, block) {
  731. super(scopeManager, "global", null, block, false);
  732. this.implicit = {
  733. set: new Map(),
  734. variables: [],
  735. /**
  736. * List of {@link Reference}s that are left to be resolved (i.e. which
  737. * need to be linked to the variable they refer to).
  738. * @member {Reference[]} Scope#implicit#left
  739. */
  740. left: []
  741. };
  742. }
  743. __close(scopeManager) {
  744. const implicit = [];
  745. for (let i = 0, iz = this.__left.length; i < iz; ++i) {
  746. const ref = this.__left[i];
  747. if (ref.__maybeImplicitGlobal && !this.set.has(ref.identifier.name)) {
  748. implicit.push(ref.__maybeImplicitGlobal);
  749. }
  750. }
  751. // create an implicit global variable from assignment expression
  752. for (let i = 0, iz = implicit.length; i < iz; ++i) {
  753. const info = implicit[i];
  754. this.__defineImplicit(info.pattern,
  755. new Definition(
  756. Variable.ImplicitGlobalVariable,
  757. info.pattern,
  758. info.node,
  759. null,
  760. null,
  761. null
  762. ));
  763. }
  764. this.implicit.left = this.__left;
  765. return super.__close(scopeManager);
  766. }
  767. __defineImplicit(node, def) {
  768. if (node && node.type === Syntax$2.Identifier) {
  769. this.__defineGeneric(
  770. node.name,
  771. this.implicit.set,
  772. this.implicit.variables,
  773. node,
  774. def
  775. );
  776. }
  777. }
  778. }
  779. /**
  780. * Module scope.
  781. */
  782. class ModuleScope extends Scope {
  783. constructor(scopeManager, upperScope, block) {
  784. super(scopeManager, "module", upperScope, block, false);
  785. }
  786. }
  787. /**
  788. * Function expression name scope.
  789. */
  790. class FunctionExpressionNameScope extends Scope {
  791. constructor(scopeManager, upperScope, block) {
  792. super(scopeManager, "function-expression-name", upperScope, block, false);
  793. this.__define(block.id,
  794. new Definition(
  795. Variable.FunctionName,
  796. block.id,
  797. block,
  798. null,
  799. null,
  800. null
  801. ));
  802. this.functionExpressionScope = true;
  803. }
  804. }
  805. /**
  806. * Catch scope.
  807. */
  808. class CatchScope extends Scope {
  809. constructor(scopeManager, upperScope, block) {
  810. super(scopeManager, "catch", upperScope, block, false);
  811. }
  812. }
  813. /**
  814. * With statement scope.
  815. */
  816. class WithScope extends Scope {
  817. constructor(scopeManager, upperScope, block) {
  818. super(scopeManager, "with", upperScope, block, false);
  819. }
  820. __close(scopeManager) {
  821. if (this.__shouldStaticallyClose(scopeManager)) {
  822. return super.__close(scopeManager);
  823. }
  824. for (let i = 0, iz = this.__left.length; i < iz; ++i) {
  825. const ref = this.__left[i];
  826. ref.tainted = true;
  827. this.__delegateToUpperScope(ref);
  828. }
  829. this.__left = null;
  830. return this.upper;
  831. }
  832. }
  833. /**
  834. * Block scope.
  835. */
  836. class BlockScope extends Scope {
  837. constructor(scopeManager, upperScope, block) {
  838. super(scopeManager, "block", upperScope, block, false);
  839. }
  840. }
  841. /**
  842. * Switch scope.
  843. */
  844. class SwitchScope extends Scope {
  845. constructor(scopeManager, upperScope, block) {
  846. super(scopeManager, "switch", upperScope, block, false);
  847. }
  848. }
  849. /**
  850. * Function scope.
  851. */
  852. class FunctionScope extends Scope {
  853. constructor(scopeManager, upperScope, block, isMethodDefinition) {
  854. super(scopeManager, "function", upperScope, block, isMethodDefinition);
  855. // section 9.2.13, FunctionDeclarationInstantiation.
  856. // NOTE Arrow functions never have an arguments objects.
  857. if (this.block.type !== Syntax$2.ArrowFunctionExpression) {
  858. this.__defineArguments();
  859. }
  860. }
  861. isArgumentsMaterialized() {
  862. // TODO(Constellation)
  863. // We can more aggressive on this condition like this.
  864. //
  865. // function t() {
  866. // // arguments of t is always hidden.
  867. // function arguments() {
  868. // }
  869. // }
  870. if (this.block.type === Syntax$2.ArrowFunctionExpression) {
  871. return false;
  872. }
  873. if (!this.isStatic()) {
  874. return true;
  875. }
  876. const variable = this.set.get("arguments");
  877. assert(variable, "Always have arguments variable.");
  878. return variable.tainted || variable.references.length !== 0;
  879. }
  880. isThisMaterialized() {
  881. if (!this.isStatic()) {
  882. return true;
  883. }
  884. return this.thisFound;
  885. }
  886. __defineArguments() {
  887. this.__defineGeneric(
  888. "arguments",
  889. this.set,
  890. this.variables,
  891. null,
  892. null
  893. );
  894. this.taints.set("arguments", true);
  895. }
  896. // References in default parameters isn't resolved to variables which are in their function body.
  897. // const x = 1
  898. // function f(a = x) { // This `x` is resolved to the `x` in the outer scope.
  899. // const x = 2
  900. // console.log(a)
  901. // }
  902. __isValidResolution(ref, variable) {
  903. // If `options.nodejsScope` is true, `this.block` becomes a Program node.
  904. if (this.block.type === "Program") {
  905. return true;
  906. }
  907. const bodyStart = this.block.body.range[0];
  908. // It's invalid resolution in the following case:
  909. return !(
  910. variable.scope === this &&
  911. ref.identifier.range[0] < bodyStart && // the reference is in the parameter part.
  912. variable.defs.every(d => d.name.range[0] >= bodyStart) // the variable is in the body.
  913. );
  914. }
  915. }
  916. /**
  917. * Scope of for, for-in, and for-of statements.
  918. */
  919. class ForScope extends Scope {
  920. constructor(scopeManager, upperScope, block) {
  921. super(scopeManager, "for", upperScope, block, false);
  922. }
  923. }
  924. /**
  925. * Class scope.
  926. */
  927. class ClassScope extends Scope {
  928. constructor(scopeManager, upperScope, block) {
  929. super(scopeManager, "class", upperScope, block, false);
  930. }
  931. }
  932. /**
  933. * Class field initializer scope.
  934. */
  935. class ClassFieldInitializerScope extends Scope {
  936. constructor(scopeManager, upperScope, block) {
  937. super(scopeManager, "class-field-initializer", upperScope, block, true);
  938. }
  939. }
  940. /**
  941. * Class static block scope.
  942. */
  943. class ClassStaticBlockScope extends Scope {
  944. constructor(scopeManager, upperScope, block) {
  945. super(scopeManager, "class-static-block", upperScope, block, true);
  946. }
  947. }
  948. /* vim: set sw=4 ts=4 et tw=80 : */
  949. /*
  950. Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
  951. Redistribution and use in source and binary forms, with or without
  952. modification, are permitted provided that the following conditions are met:
  953. * Redistributions of source code must retain the above copyright
  954. notice, this list of conditions and the following disclaimer.
  955. * Redistributions in binary form must reproduce the above copyright
  956. notice, this list of conditions and the following disclaimer in the
  957. documentation and/or other materials provided with the distribution.
  958. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  959. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  960. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  961. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  962. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  963. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  964. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  965. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  966. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  967. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  968. */
  969. /**
  970. * @constructor ScopeManager
  971. */
  972. class ScopeManager {
  973. constructor(options) {
  974. this.scopes = [];
  975. this.globalScope = null;
  976. this.__nodeToScope = new WeakMap();
  977. this.__currentScope = null;
  978. this.__options = options;
  979. this.__declaredVariables = new WeakMap();
  980. }
  981. __isOptimistic() {
  982. return this.__options.optimistic;
  983. }
  984. __ignoreEval() {
  985. return this.__options.ignoreEval;
  986. }
  987. isGlobalReturn() {
  988. return this.__options.nodejsScope || this.__options.sourceType === "commonjs";
  989. }
  990. isModule() {
  991. return this.__options.sourceType === "module";
  992. }
  993. isImpliedStrict() {
  994. return this.__options.impliedStrict;
  995. }
  996. isStrictModeSupported() {
  997. return this.__options.ecmaVersion >= 5;
  998. }
  999. // Returns appropriate scope for this node.
  1000. __get(node) {
  1001. return this.__nodeToScope.get(node);
  1002. }
  1003. /**
  1004. * Get variables that are declared by the node.
  1005. *
  1006. * "are declared by the node" means the node is same as `Variable.defs[].node` or `Variable.defs[].parent`.
  1007. * If the node declares nothing, this method returns an empty array.
  1008. * CAUTION: This API is experimental. See https://github.com/estools/escope/pull/69 for more details.
  1009. * @param {Espree.Node} node a node to get.
  1010. * @returns {Variable[]} variables that declared by the node.
  1011. */
  1012. getDeclaredVariables(node) {
  1013. return this.__declaredVariables.get(node) || [];
  1014. }
  1015. /**
  1016. * acquire scope from node.
  1017. * @function ScopeManager#acquire
  1018. * @param {Espree.Node} node node for the acquired scope.
  1019. * @param {?boolean} [inner=false] look up the most inner scope, default value is false.
  1020. * @returns {Scope?} Scope from node
  1021. */
  1022. acquire(node, inner) {
  1023. /**
  1024. * predicate
  1025. * @param {Scope} testScope scope to test
  1026. * @returns {boolean} predicate
  1027. */
  1028. function predicate(testScope) {
  1029. if (testScope.type === "function" && testScope.functionExpressionScope) {
  1030. return false;
  1031. }
  1032. return true;
  1033. }
  1034. const scopes = this.__get(node);
  1035. if (!scopes || scopes.length === 0) {
  1036. return null;
  1037. }
  1038. // Heuristic selection from all scopes.
  1039. // If you would like to get all scopes, please use ScopeManager#acquireAll.
  1040. if (scopes.length === 1) {
  1041. return scopes[0];
  1042. }
  1043. if (inner) {
  1044. for (let i = scopes.length - 1; i >= 0; --i) {
  1045. const scope = scopes[i];
  1046. if (predicate(scope)) {
  1047. return scope;
  1048. }
  1049. }
  1050. } else {
  1051. for (let i = 0, iz = scopes.length; i < iz; ++i) {
  1052. const scope = scopes[i];
  1053. if (predicate(scope)) {
  1054. return scope;
  1055. }
  1056. }
  1057. }
  1058. return null;
  1059. }
  1060. /**
  1061. * acquire all scopes from node.
  1062. * @function ScopeManager#acquireAll
  1063. * @param {Espree.Node} node node for the acquired scope.
  1064. * @returns {Scopes?} Scope array
  1065. */
  1066. acquireAll(node) {
  1067. return this.__get(node);
  1068. }
  1069. /**
  1070. * release the node.
  1071. * @function ScopeManager#release
  1072. * @param {Espree.Node} node releasing node.
  1073. * @param {?boolean} [inner=false] look up the most inner scope, default value is false.
  1074. * @returns {Scope?} upper scope for the node.
  1075. */
  1076. release(node, inner) {
  1077. const scopes = this.__get(node);
  1078. if (scopes && scopes.length) {
  1079. const scope = scopes[0].upper;
  1080. if (!scope) {
  1081. return null;
  1082. }
  1083. return this.acquire(scope.block, inner);
  1084. }
  1085. return null;
  1086. }
  1087. attach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method
  1088. detach() { } // eslint-disable-line class-methods-use-this -- Desired as instance method
  1089. __nestScope(scope) {
  1090. if (scope instanceof GlobalScope) {
  1091. assert(this.__currentScope === null);
  1092. this.globalScope = scope;
  1093. }
  1094. this.__currentScope = scope;
  1095. return scope;
  1096. }
  1097. __nestGlobalScope(node) {
  1098. return this.__nestScope(new GlobalScope(this, node));
  1099. }
  1100. __nestBlockScope(node) {
  1101. return this.__nestScope(new BlockScope(this, this.__currentScope, node));
  1102. }
  1103. __nestFunctionScope(node, isMethodDefinition) {
  1104. return this.__nestScope(new FunctionScope(this, this.__currentScope, node, isMethodDefinition));
  1105. }
  1106. __nestForScope(node) {
  1107. return this.__nestScope(new ForScope(this, this.__currentScope, node));
  1108. }
  1109. __nestCatchScope(node) {
  1110. return this.__nestScope(new CatchScope(this, this.__currentScope, node));
  1111. }
  1112. __nestWithScope(node) {
  1113. return this.__nestScope(new WithScope(this, this.__currentScope, node));
  1114. }
  1115. __nestClassScope(node) {
  1116. return this.__nestScope(new ClassScope(this, this.__currentScope, node));
  1117. }
  1118. __nestClassFieldInitializerScope(node) {
  1119. return this.__nestScope(new ClassFieldInitializerScope(this, this.__currentScope, node));
  1120. }
  1121. __nestClassStaticBlockScope(node) {
  1122. return this.__nestScope(new ClassStaticBlockScope(this, this.__currentScope, node));
  1123. }
  1124. __nestSwitchScope(node) {
  1125. return this.__nestScope(new SwitchScope(this, this.__currentScope, node));
  1126. }
  1127. __nestModuleScope(node) {
  1128. return this.__nestScope(new ModuleScope(this, this.__currentScope, node));
  1129. }
  1130. __nestFunctionExpressionNameScope(node) {
  1131. return this.__nestScope(new FunctionExpressionNameScope(this, this.__currentScope, node));
  1132. }
  1133. __isES6() {
  1134. return this.__options.ecmaVersion >= 6;
  1135. }
  1136. }
  1137. /* vim: set sw=4 ts=4 et tw=80 : */
  1138. /*
  1139. Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
  1140. Redistribution and use in source and binary forms, with or without
  1141. modification, are permitted provided that the following conditions are met:
  1142. * Redistributions of source code must retain the above copyright
  1143. notice, this list of conditions and the following disclaimer.
  1144. * Redistributions in binary form must reproduce the above copyright
  1145. notice, this list of conditions and the following disclaimer in the
  1146. documentation and/or other materials provided with the distribution.
  1147. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  1148. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1149. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1150. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  1151. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1152. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1153. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  1154. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1155. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1156. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1157. */
  1158. const { Syntax: Syntax$1 } = estraverse__default["default"];
  1159. /**
  1160. * Get last array element
  1161. * @param {Array} xs array
  1162. * @returns {any} Last elment
  1163. */
  1164. function getLast(xs) {
  1165. return xs.at(-1) || null;
  1166. }
  1167. /**
  1168. * Visitor for destructuring patterns.
  1169. */
  1170. class PatternVisitor extends esrecurse__default["default"].Visitor {
  1171. static isPattern(node) {
  1172. const nodeType = node.type;
  1173. return (
  1174. nodeType === Syntax$1.Identifier ||
  1175. nodeType === Syntax$1.ObjectPattern ||
  1176. nodeType === Syntax$1.ArrayPattern ||
  1177. nodeType === Syntax$1.SpreadElement ||
  1178. nodeType === Syntax$1.RestElement ||
  1179. nodeType === Syntax$1.AssignmentPattern
  1180. );
  1181. }
  1182. constructor(options, rootPattern, callback) {
  1183. super(null, options);
  1184. this.rootPattern = rootPattern;
  1185. this.callback = callback;
  1186. this.assignments = [];
  1187. this.rightHandNodes = [];
  1188. this.restElements = [];
  1189. }
  1190. Identifier(pattern) {
  1191. const lastRestElement = getLast(this.restElements);
  1192. this.callback(pattern, {
  1193. topLevel: pattern === this.rootPattern,
  1194. rest: lastRestElement !== null && lastRestElement !== void 0 && lastRestElement.argument === pattern,
  1195. assignments: this.assignments
  1196. });
  1197. }
  1198. Property(property) {
  1199. // Computed property's key is a right hand node.
  1200. if (property.computed) {
  1201. this.rightHandNodes.push(property.key);
  1202. }
  1203. // If it's shorthand, its key is same as its value.
  1204. // If it's shorthand and has its default value, its key is same as its value.left (the value is AssignmentPattern).
  1205. // If it's not shorthand, the name of new variable is its value's.
  1206. this.visit(property.value);
  1207. }
  1208. ArrayPattern(pattern) {
  1209. for (let i = 0, iz = pattern.elements.length; i < iz; ++i) {
  1210. const element = pattern.elements[i];
  1211. this.visit(element);
  1212. }
  1213. }
  1214. AssignmentPattern(pattern) {
  1215. this.assignments.push(pattern);
  1216. this.visit(pattern.left);
  1217. this.rightHandNodes.push(pattern.right);
  1218. this.assignments.pop();
  1219. }
  1220. RestElement(pattern) {
  1221. this.restElements.push(pattern);
  1222. this.visit(pattern.argument);
  1223. this.restElements.pop();
  1224. }
  1225. MemberExpression(node) {
  1226. // Computed property's key is a right hand node.
  1227. if (node.computed) {
  1228. this.rightHandNodes.push(node.property);
  1229. }
  1230. // the object is only read, write to its property.
  1231. this.rightHandNodes.push(node.object);
  1232. }
  1233. //
  1234. // ForInStatement.left and AssignmentExpression.left are LeftHandSideExpression.
  1235. // By spec, LeftHandSideExpression is Pattern or MemberExpression.
  1236. // (see also: https://github.com/estree/estree/pull/20#issuecomment-74584758)
  1237. // But espree 2.0 parses to ArrayExpression, ObjectExpression, etc...
  1238. //
  1239. SpreadElement(node) {
  1240. this.visit(node.argument);
  1241. }
  1242. ArrayExpression(node) {
  1243. node.elements.forEach(this.visit, this);
  1244. }
  1245. AssignmentExpression(node) {
  1246. this.assignments.push(node);
  1247. this.visit(node.left);
  1248. this.rightHandNodes.push(node.right);
  1249. this.assignments.pop();
  1250. }
  1251. CallExpression(node) {
  1252. // arguments are right hand nodes.
  1253. node.arguments.forEach(a => {
  1254. this.rightHandNodes.push(a);
  1255. });
  1256. this.visit(node.callee);
  1257. }
  1258. }
  1259. /* vim: set sw=4 ts=4 et tw=80 : */
  1260. /*
  1261. Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>
  1262. Redistribution and use in source and binary forms, with or without
  1263. modification, are permitted provided that the following conditions are met:
  1264. * Redistributions of source code must retain the above copyright
  1265. notice, this list of conditions and the following disclaimer.
  1266. * Redistributions in binary form must reproduce the above copyright
  1267. notice, this list of conditions and the following disclaimer in the
  1268. documentation and/or other materials provided with the distribution.
  1269. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  1270. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1271. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1272. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  1273. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1274. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1275. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  1276. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1277. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1278. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1279. */
  1280. const { Syntax } = estraverse__default["default"];
  1281. /**
  1282. * Traverse identifier in pattern
  1283. * @param {Object} options options
  1284. * @param {pattern} rootPattern root pattern
  1285. * @param {Refencer} referencer referencer
  1286. * @param {callback} callback callback
  1287. * @returns {void}
  1288. */
  1289. function traverseIdentifierInPattern(options, rootPattern, referencer, callback) {
  1290. // Call the callback at left hand identifier nodes, and Collect right hand nodes.
  1291. const visitor = new PatternVisitor(options, rootPattern, callback);
  1292. visitor.visit(rootPattern);
  1293. // Process the right hand nodes recursively.
  1294. if (referencer !== null && referencer !== void 0) {
  1295. visitor.rightHandNodes.forEach(referencer.visit, referencer);
  1296. }
  1297. }
  1298. // Importing ImportDeclaration.
  1299. // http://people.mozilla.org/~jorendorff/es6-draft.html#sec-moduledeclarationinstantiation
  1300. // https://github.com/estree/estree/blob/master/es6.md#importdeclaration
  1301. // FIXME: Now, we don't create module environment, because the context is
  1302. // implementation dependent.
  1303. /**
  1304. * Visitor for import specifiers.
  1305. */
  1306. class Importer extends esrecurse__default["default"].Visitor {
  1307. constructor(declaration, referencer) {
  1308. super(null, referencer.options);
  1309. this.declaration = declaration;
  1310. this.referencer = referencer;
  1311. }
  1312. visitImport(id, specifier) {
  1313. this.referencer.visitPattern(id, pattern => {
  1314. this.referencer.currentScope().__define(pattern,
  1315. new Definition(
  1316. Variable.ImportBinding,
  1317. pattern,
  1318. specifier,
  1319. this.declaration,
  1320. null,
  1321. null
  1322. ));
  1323. });
  1324. }
  1325. ImportNamespaceSpecifier(node) {
  1326. const local = (node.local || node.id);
  1327. if (local) {
  1328. this.visitImport(local, node);
  1329. }
  1330. }
  1331. ImportDefaultSpecifier(node) {
  1332. const local = (node.local || node.id);
  1333. this.visitImport(local, node);
  1334. }
  1335. ImportSpecifier(node) {
  1336. const local = (node.local || node.id);
  1337. if (node.name) {
  1338. this.visitImport(node.name, node);
  1339. } else {
  1340. this.visitImport(local, node);
  1341. }
  1342. }
  1343. }
  1344. /**
  1345. * Referencing variables and creating bindings.
  1346. */
  1347. class Referencer extends esrecurse__default["default"].Visitor {
  1348. constructor(options, scopeManager) {
  1349. super(null, options);
  1350. this.options = options;
  1351. this.scopeManager = scopeManager;
  1352. this.parent = null;
  1353. this.isInnerMethodDefinition = false;
  1354. }
  1355. currentScope() {
  1356. return this.scopeManager.__currentScope;
  1357. }
  1358. close(node) {
  1359. while (this.currentScope() && node === this.currentScope().block) {
  1360. this.scopeManager.__currentScope = this.currentScope().__close(this.scopeManager);
  1361. }
  1362. }
  1363. pushInnerMethodDefinition(isInnerMethodDefinition) {
  1364. const previous = this.isInnerMethodDefinition;
  1365. this.isInnerMethodDefinition = isInnerMethodDefinition;
  1366. return previous;
  1367. }
  1368. popInnerMethodDefinition(isInnerMethodDefinition) {
  1369. this.isInnerMethodDefinition = isInnerMethodDefinition;
  1370. }
  1371. referencingDefaultValue(pattern, assignments, maybeImplicitGlobal, init) {
  1372. const scope = this.currentScope();
  1373. assignments.forEach(assignment => {
  1374. scope.__referencing(
  1375. pattern,
  1376. Reference.WRITE,
  1377. assignment.right,
  1378. maybeImplicitGlobal,
  1379. pattern !== assignment.left,
  1380. init
  1381. );
  1382. });
  1383. }
  1384. visitPattern(node, options, callback) {
  1385. let visitPatternOptions = options;
  1386. let visitPatternCallback = callback;
  1387. if (typeof options === "function") {
  1388. visitPatternCallback = options;
  1389. visitPatternOptions = { processRightHandNodes: false };
  1390. }
  1391. traverseIdentifierInPattern(
  1392. this.options,
  1393. node,
  1394. visitPatternOptions.processRightHandNodes ? this : null,
  1395. visitPatternCallback
  1396. );
  1397. }
  1398. visitFunction(node) {
  1399. let i, iz;
  1400. // FunctionDeclaration name is defined in upper scope
  1401. // NOTE: Not referring variableScope. It is intended.
  1402. // Since
  1403. // in ES5, FunctionDeclaration should be in FunctionBody.
  1404. // in ES6, FunctionDeclaration should be block scoped.
  1405. if (node.type === Syntax.FunctionDeclaration) {
  1406. // id is defined in upper scope
  1407. this.currentScope().__define(node.id,
  1408. new Definition(
  1409. Variable.FunctionName,
  1410. node.id,
  1411. node,
  1412. null,
  1413. null,
  1414. null
  1415. ));
  1416. }
  1417. // FunctionExpression with name creates its special scope;
  1418. // FunctionExpressionNameScope.
  1419. if (node.type === Syntax.FunctionExpression && node.id) {
  1420. this.scopeManager.__nestFunctionExpressionNameScope(node);
  1421. }
  1422. // Consider this function is in the MethodDefinition.
  1423. this.scopeManager.__nestFunctionScope(node, this.isInnerMethodDefinition);
  1424. const that = this;
  1425. /**
  1426. * Visit pattern callback
  1427. * @param {pattern} pattern pattern
  1428. * @param {Object} info info
  1429. * @returns {void}
  1430. */
  1431. function visitPatternCallback(pattern, info) {
  1432. that.currentScope().__define(pattern,
  1433. new ParameterDefinition(
  1434. pattern,
  1435. node,
  1436. i,
  1437. info.rest
  1438. ));
  1439. that.referencingDefaultValue(pattern, info.assignments, null, true);
  1440. }
  1441. // Process parameter declarations.
  1442. for (i = 0, iz = node.params.length; i < iz; ++i) {
  1443. this.visitPattern(node.params[i], { processRightHandNodes: true }, visitPatternCallback);
  1444. }
  1445. // if there's a rest argument, add that
  1446. if (node.rest) {
  1447. this.visitPattern({
  1448. type: "RestElement",
  1449. argument: node.rest
  1450. }, pattern => {
  1451. this.currentScope().__define(pattern,
  1452. new ParameterDefinition(
  1453. pattern,
  1454. node,
  1455. node.params.length,
  1456. true
  1457. ));
  1458. });
  1459. }
  1460. // In TypeScript there are a number of function-like constructs which have no body,
  1461. // so check it exists before traversing
  1462. if (node.body) {
  1463. // Skip BlockStatement to prevent creating BlockStatement scope.
  1464. if (node.body.type === Syntax.BlockStatement) {
  1465. this.visitChildren(node.body);
  1466. } else {
  1467. this.visit(node.body);
  1468. }
  1469. }
  1470. this.close(node);
  1471. }
  1472. visitClass(node) {
  1473. if (node.type === Syntax.ClassDeclaration) {
  1474. this.currentScope().__define(node.id,
  1475. new Definition(
  1476. Variable.ClassName,
  1477. node.id,
  1478. node,
  1479. null,
  1480. null,
  1481. null
  1482. ));
  1483. }
  1484. this.scopeManager.__nestClassScope(node);
  1485. if (node.id) {
  1486. this.currentScope().__define(node.id,
  1487. new Definition(
  1488. Variable.ClassName,
  1489. node.id,
  1490. node
  1491. ));
  1492. }
  1493. this.visit(node.superClass);
  1494. this.visit(node.body);
  1495. this.close(node);
  1496. }
  1497. visitProperty(node) {
  1498. let previous;
  1499. if (node.computed) {
  1500. this.visit(node.key);
  1501. }
  1502. const isMethodDefinition = node.type === Syntax.MethodDefinition;
  1503. if (isMethodDefinition) {
  1504. previous = this.pushInnerMethodDefinition(true);
  1505. }
  1506. this.visit(node.value);
  1507. if (isMethodDefinition) {
  1508. this.popInnerMethodDefinition(previous);
  1509. }
  1510. }
  1511. visitForIn(node) {
  1512. if (node.left.type === Syntax.VariableDeclaration && node.left.kind !== "var") {
  1513. this.scopeManager.__nestForScope(node);
  1514. }
  1515. if (node.left.type === Syntax.VariableDeclaration) {
  1516. this.visit(node.left);
  1517. this.visitPattern(node.left.declarations[0].id, pattern => {
  1518. this.currentScope().__referencing(pattern, Reference.WRITE, node.right, null, true, true);
  1519. });
  1520. } else {
  1521. this.visitPattern(node.left, { processRightHandNodes: true }, (pattern, info) => {
  1522. let maybeImplicitGlobal = null;
  1523. if (!this.currentScope().isStrict) {
  1524. maybeImplicitGlobal = {
  1525. pattern,
  1526. node
  1527. };
  1528. }
  1529. this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false);
  1530. this.currentScope().__referencing(pattern, Reference.WRITE, node.right, maybeImplicitGlobal, true, false);
  1531. });
  1532. }
  1533. this.visit(node.right);
  1534. this.visit(node.body);
  1535. this.close(node);
  1536. }
  1537. visitVariableDeclaration(variableTargetScope, type, node, index) {
  1538. const decl = node.declarations[index];
  1539. const init = decl.init;
  1540. this.visitPattern(decl.id, { processRightHandNodes: true }, (pattern, info) => {
  1541. variableTargetScope.__define(
  1542. pattern,
  1543. new Definition(
  1544. type,
  1545. pattern,
  1546. decl,
  1547. node,
  1548. index,
  1549. node.kind
  1550. )
  1551. );
  1552. this.referencingDefaultValue(pattern, info.assignments, null, true);
  1553. if (init) {
  1554. this.currentScope().__referencing(pattern, Reference.WRITE, init, null, !info.topLevel, true);
  1555. }
  1556. });
  1557. }
  1558. AssignmentExpression(node) {
  1559. if (PatternVisitor.isPattern(node.left)) {
  1560. if (node.operator === "=") {
  1561. this.visitPattern(node.left, { processRightHandNodes: true }, (pattern, info) => {
  1562. let maybeImplicitGlobal = null;
  1563. if (!this.currentScope().isStrict) {
  1564. maybeImplicitGlobal = {
  1565. pattern,
  1566. node
  1567. };
  1568. }
  1569. this.referencingDefaultValue(pattern, info.assignments, maybeImplicitGlobal, false);
  1570. this.currentScope().__referencing(pattern, Reference.WRITE, node.right, maybeImplicitGlobal, !info.topLevel, false);
  1571. });
  1572. } else {
  1573. this.currentScope().__referencing(node.left, Reference.RW, node.right);
  1574. }
  1575. } else {
  1576. this.visit(node.left);
  1577. }
  1578. this.visit(node.right);
  1579. }
  1580. CatchClause(node) {
  1581. this.scopeManager.__nestCatchScope(node);
  1582. this.visitPattern(node.param, { processRightHandNodes: true }, (pattern, info) => {
  1583. this.currentScope().__define(pattern,
  1584. new Definition(
  1585. Variable.CatchClause,
  1586. pattern,
  1587. node,
  1588. null,
  1589. null,
  1590. null
  1591. ));
  1592. this.referencingDefaultValue(pattern, info.assignments, null, true);
  1593. });
  1594. this.visit(node.body);
  1595. this.close(node);
  1596. }
  1597. Program(node) {
  1598. this.scopeManager.__nestGlobalScope(node);
  1599. if (this.scopeManager.isGlobalReturn()) {
  1600. // Force strictness of GlobalScope to false when using node.js scope.
  1601. this.currentScope().isStrict = false;
  1602. this.scopeManager.__nestFunctionScope(node, false);
  1603. }
  1604. if (this.scopeManager.__isES6() && this.scopeManager.isModule()) {
  1605. this.scopeManager.__nestModuleScope(node);
  1606. }
  1607. if (this.scopeManager.isStrictModeSupported() && this.scopeManager.isImpliedStrict()) {
  1608. this.currentScope().isStrict = true;
  1609. }
  1610. this.visitChildren(node);
  1611. this.close(node);
  1612. }
  1613. Identifier(node) {
  1614. this.currentScope().__referencing(node);
  1615. }
  1616. // eslint-disable-next-line class-methods-use-this -- Desired as instance method
  1617. PrivateIdentifier() {
  1618. // Do nothing.
  1619. }
  1620. UpdateExpression(node) {
  1621. if (PatternVisitor.isPattern(node.argument)) {
  1622. this.currentScope().__referencing(node.argument, Reference.RW, null);
  1623. } else {
  1624. this.visitChildren(node);
  1625. }
  1626. }
  1627. MemberExpression(node) {
  1628. this.visit(node.object);
  1629. if (node.computed) {
  1630. this.visit(node.property);
  1631. }
  1632. }
  1633. Property(node) {
  1634. this.visitProperty(node);
  1635. }
  1636. PropertyDefinition(node) {
  1637. const { computed, key, value } = node;
  1638. if (computed) {
  1639. this.visit(key);
  1640. }
  1641. if (value) {
  1642. this.scopeManager.__nestClassFieldInitializerScope(value);
  1643. this.visit(value);
  1644. this.close(value);
  1645. }
  1646. }
  1647. StaticBlock(node) {
  1648. this.scopeManager.__nestClassStaticBlockScope(node);
  1649. this.visitChildren(node);
  1650. this.close(node);
  1651. }
  1652. MethodDefinition(node) {
  1653. this.visitProperty(node);
  1654. }
  1655. BreakStatement() {} // eslint-disable-line class-methods-use-this -- Desired as instance method
  1656. ContinueStatement() {} // eslint-disable-line class-methods-use-this -- Desired as instance method
  1657. LabeledStatement(node) {
  1658. this.visit(node.body);
  1659. }
  1660. ForStatement(node) {
  1661. // Create ForStatement declaration.
  1662. // NOTE: In ES6, ForStatement dynamically generates
  1663. // per iteration environment. However, escope is
  1664. // a static analyzer, we only generate one scope for ForStatement.
  1665. if (node.init && node.init.type === Syntax.VariableDeclaration && node.init.kind !== "var") {
  1666. this.scopeManager.__nestForScope(node);
  1667. }
  1668. this.visitChildren(node);
  1669. this.close(node);
  1670. }
  1671. ClassExpression(node) {
  1672. this.visitClass(node);
  1673. }
  1674. ClassDeclaration(node) {
  1675. this.visitClass(node);
  1676. }
  1677. CallExpression(node) {
  1678. // Check this is direct call to eval
  1679. if (!this.scopeManager.__ignoreEval() && node.callee.type === Syntax.Identifier && node.callee.name === "eval") {
  1680. // NOTE: This should be `variableScope`. Since direct eval call always creates Lexical environment and
  1681. // let / const should be enclosed into it. Only VariableDeclaration affects on the caller's environment.
  1682. this.currentScope().variableScope.__detectEval();
  1683. }
  1684. this.visitChildren(node);
  1685. }
  1686. BlockStatement(node) {
  1687. if (this.scopeManager.__isES6()) {
  1688. this.scopeManager.__nestBlockScope(node);
  1689. }
  1690. this.visitChildren(node);
  1691. this.close(node);
  1692. }
  1693. ThisExpression() {
  1694. this.currentScope().variableScope.__detectThis();
  1695. }
  1696. WithStatement(node) {
  1697. this.visit(node.object);
  1698. // Then nest scope for WithStatement.
  1699. this.scopeManager.__nestWithScope(node);
  1700. this.visit(node.body);
  1701. this.close(node);
  1702. }
  1703. VariableDeclaration(node) {
  1704. const variableTargetScope = (node.kind === "var") ? this.currentScope().variableScope : this.currentScope();
  1705. for (let i = 0, iz = node.declarations.length; i < iz; ++i) {
  1706. const decl = node.declarations[i];
  1707. this.visitVariableDeclaration(variableTargetScope, Variable.Variable, node, i);
  1708. if (decl.init) {
  1709. this.visit(decl.init);
  1710. }
  1711. }
  1712. }
  1713. // sec 13.11.8
  1714. SwitchStatement(node) {
  1715. this.visit(node.discriminant);
  1716. if (this.scopeManager.__isES6()) {
  1717. this.scopeManager.__nestSwitchScope(node);
  1718. }
  1719. for (let i = 0, iz = node.cases.length; i < iz; ++i) {
  1720. this.visit(node.cases[i]);
  1721. }
  1722. this.close(node);
  1723. }
  1724. FunctionDeclaration(node) {
  1725. this.visitFunction(node);
  1726. }
  1727. FunctionExpression(node) {
  1728. this.visitFunction(node);
  1729. }
  1730. ForOfStatement(node) {
  1731. this.visitForIn(node);
  1732. }
  1733. ForInStatement(node) {
  1734. this.visitForIn(node);
  1735. }
  1736. ArrowFunctionExpression(node) {
  1737. this.visitFunction(node);
  1738. }
  1739. ImportDeclaration(node) {
  1740. assert(this.scopeManager.__isES6() && this.scopeManager.isModule(), "ImportDeclaration should appear when the mode is ES6 and in the module context.");
  1741. const importer = new Importer(node, this);
  1742. importer.visit(node);
  1743. }
  1744. visitExportDeclaration(node) {
  1745. if (node.source) {
  1746. return;
  1747. }
  1748. if (node.declaration) {
  1749. this.visit(node.declaration);
  1750. return;
  1751. }
  1752. this.visitChildren(node);
  1753. }
  1754. // TODO: ExportDeclaration doesn't exist. for bc?
  1755. ExportDeclaration(node) {
  1756. this.visitExportDeclaration(node);
  1757. }
  1758. ExportAllDeclaration(node) {
  1759. this.visitExportDeclaration(node);
  1760. }
  1761. ExportDefaultDeclaration(node) {
  1762. this.visitExportDeclaration(node);
  1763. }
  1764. ExportNamedDeclaration(node) {
  1765. this.visitExportDeclaration(node);
  1766. }
  1767. ExportSpecifier(node) {
  1768. // TODO: `node.id` doesn't exist. for bc?
  1769. const local = (node.id || node.local);
  1770. this.visit(local);
  1771. }
  1772. MetaProperty() { // eslint-disable-line class-methods-use-this -- Desired as instance method
  1773. // do nothing.
  1774. }
  1775. }
  1776. /* vim: set sw=4 ts=4 et tw=80 : */
  1777. const version = "8.1.0";
  1778. /*
  1779. Copyright (C) 2012-2014 Yusuke Suzuki <utatane.tea@gmail.com>
  1780. Copyright (C) 2013 Alex Seville <hi@alexanderseville.com>
  1781. Copyright (C) 2014 Thiago de Arruda <tpadilha84@gmail.com>
  1782. Redistribution and use in source and binary forms, with or without
  1783. modification, are permitted provided that the following conditions are met:
  1784. * Redistributions of source code must retain the above copyright
  1785. notice, this list of conditions and the following disclaimer.
  1786. * Redistributions in binary form must reproduce the above copyright
  1787. notice, this list of conditions and the following disclaimer in the
  1788. documentation and/or other materials provided with the distribution.
  1789. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  1790. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1791. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1792. ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  1793. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  1794. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  1795. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  1796. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1797. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1798. THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1799. */
  1800. /**
  1801. * Set the default options
  1802. * @returns {Object} options
  1803. */
  1804. function defaultOptions() {
  1805. return {
  1806. optimistic: false,
  1807. nodejsScope: false,
  1808. impliedStrict: false,
  1809. sourceType: "script", // one of ['script', 'module', 'commonjs']
  1810. ecmaVersion: 5,
  1811. childVisitorKeys: null,
  1812. fallback: "iteration"
  1813. };
  1814. }
  1815. /**
  1816. * Preform deep update on option object
  1817. * @param {Object} target Options
  1818. * @param {Object} override Updates
  1819. * @returns {Object} Updated options
  1820. */
  1821. function updateDeeply(target, override) {
  1822. /**
  1823. * Is hash object
  1824. * @param {Object} value Test value
  1825. * @returns {boolean} Result
  1826. */
  1827. function isHashObject(value) {
  1828. return typeof value === "object" && value instanceof Object && !(value instanceof Array) && !(value instanceof RegExp);
  1829. }
  1830. for (const key in override) {
  1831. if (Object.hasOwn(override, key)) {
  1832. const val = override[key];
  1833. if (isHashObject(val)) {
  1834. if (isHashObject(target[key])) {
  1835. updateDeeply(target[key], val);
  1836. } else {
  1837. target[key] = updateDeeply({}, val);
  1838. }
  1839. } else {
  1840. target[key] = val;
  1841. }
  1842. }
  1843. }
  1844. return target;
  1845. }
  1846. /**
  1847. * Main interface function. Takes an Espree syntax tree and returns the
  1848. * analyzed scopes.
  1849. * @function analyze
  1850. * @param {espree.Tree} tree Abstract Syntax Tree
  1851. * @param {Object} providedOptions Options that tailor the scope analysis
  1852. * @param {boolean} [providedOptions.optimistic=false] the optimistic flag
  1853. * @param {boolean} [providedOptions.ignoreEval=false] whether to check 'eval()' calls
  1854. * @param {boolean} [providedOptions.nodejsScope=false] whether the whole
  1855. * script is executed under node.js environment. When enabled, escope adds
  1856. * a function scope immediately following the global scope.
  1857. * @param {boolean} [providedOptions.impliedStrict=false] implied strict mode
  1858. * (if ecmaVersion >= 5).
  1859. * @param {string} [providedOptions.sourceType='script'] the source type of the script. one of 'script', 'module', and 'commonjs'
  1860. * @param {number} [providedOptions.ecmaVersion=5] which ECMAScript version is considered
  1861. * @param {Object} [providedOptions.childVisitorKeys=null] Additional known visitor keys. See [esrecurse](https://github.com/estools/esrecurse)'s the `childVisitorKeys` option.
  1862. * @param {string} [providedOptions.fallback='iteration'] A kind of the fallback in order to encounter with unknown node. See [esrecurse](https://github.com/estools/esrecurse)'s the `fallback` option.
  1863. * @returns {ScopeManager} ScopeManager
  1864. */
  1865. function analyze(tree, providedOptions) {
  1866. const options = updateDeeply(defaultOptions(), providedOptions);
  1867. const scopeManager = new ScopeManager(options);
  1868. const referencer = new Referencer(options, scopeManager);
  1869. referencer.visit(tree);
  1870. assert(scopeManager.__currentScope === null, "currentScope should be null.");
  1871. return scopeManager;
  1872. }
  1873. /* vim: set sw=4 ts=4 et tw=80 : */
  1874. exports.Definition = Definition;
  1875. exports.PatternVisitor = PatternVisitor;
  1876. exports.Reference = Reference;
  1877. exports.Referencer = Referencer;
  1878. exports.Scope = Scope;
  1879. exports.ScopeManager = ScopeManager;
  1880. exports.Variable = Variable;
  1881. exports.analyze = analyze;
  1882. exports.version = version;
  1883. //# sourceMappingURL=eslint-scope.cjs.map