scope.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = exports.Scope = void 0;
  6. var _scopeflags = require("./scopeflags");
  7. var _parseError = require("../parse-error");
  8. class Scope {
  9. constructor(flags) {
  10. this.var = new Set();
  11. this.lexical = new Set();
  12. this.functions = new Set();
  13. this.flags = flags;
  14. }
  15. }
  16. exports.Scope = Scope;
  17. class ScopeHandler {
  18. constructor(parser, inModule) {
  19. this.parser = void 0;
  20. this.scopeStack = [];
  21. this.inModule = void 0;
  22. this.undefinedExports = new Map();
  23. this.parser = parser;
  24. this.inModule = inModule;
  25. }
  26. get inTopLevel() {
  27. return (this.currentScope().flags & _scopeflags.SCOPE_PROGRAM) > 0;
  28. }
  29. get inFunction() {
  30. return (this.currentVarScopeFlags() & _scopeflags.SCOPE_FUNCTION) > 0;
  31. }
  32. get allowSuper() {
  33. return (this.currentThisScopeFlags() & _scopeflags.SCOPE_SUPER) > 0;
  34. }
  35. get allowDirectSuper() {
  36. return (this.currentThisScopeFlags() & _scopeflags.SCOPE_DIRECT_SUPER) > 0;
  37. }
  38. get inClass() {
  39. return (this.currentThisScopeFlags() & _scopeflags.SCOPE_CLASS) > 0;
  40. }
  41. get inClassAndNotInNonArrowFunction() {
  42. const flags = this.currentThisScopeFlags();
  43. return (flags & _scopeflags.SCOPE_CLASS) > 0 && (flags & _scopeflags.SCOPE_FUNCTION) === 0;
  44. }
  45. get inStaticBlock() {
  46. for (let i = this.scopeStack.length - 1;; i--) {
  47. const {
  48. flags
  49. } = this.scopeStack[i];
  50. if (flags & _scopeflags.SCOPE_STATIC_BLOCK) {
  51. return true;
  52. }
  53. if (flags & (_scopeflags.SCOPE_VAR | _scopeflags.SCOPE_CLASS)) {
  54. return false;
  55. }
  56. }
  57. }
  58. get inNonArrowFunction() {
  59. return (this.currentThisScopeFlags() & _scopeflags.SCOPE_FUNCTION) > 0;
  60. }
  61. get treatFunctionsAsVar() {
  62. return this.treatFunctionsAsVarInScope(this.currentScope());
  63. }
  64. createScope(flags) {
  65. return new Scope(flags);
  66. }
  67. enter(flags) {
  68. this.scopeStack.push(this.createScope(flags));
  69. }
  70. exit() {
  71. const scope = this.scopeStack.pop();
  72. return scope.flags;
  73. }
  74. treatFunctionsAsVarInScope(scope) {
  75. return !!(scope.flags & (_scopeflags.SCOPE_FUNCTION | _scopeflags.SCOPE_STATIC_BLOCK) || !this.parser.inModule && scope.flags & _scopeflags.SCOPE_PROGRAM);
  76. }
  77. declareName(name, bindingType, loc) {
  78. let scope = this.currentScope();
  79. if (bindingType & _scopeflags.BIND_SCOPE_LEXICAL || bindingType & _scopeflags.BIND_SCOPE_FUNCTION) {
  80. this.checkRedeclarationInScope(scope, name, bindingType, loc);
  81. if (bindingType & _scopeflags.BIND_SCOPE_FUNCTION) {
  82. scope.functions.add(name);
  83. } else {
  84. scope.lexical.add(name);
  85. }
  86. if (bindingType & _scopeflags.BIND_SCOPE_LEXICAL) {
  87. this.maybeExportDefined(scope, name);
  88. }
  89. } else if (bindingType & _scopeflags.BIND_SCOPE_VAR) {
  90. for (let i = this.scopeStack.length - 1; i >= 0; --i) {
  91. scope = this.scopeStack[i];
  92. this.checkRedeclarationInScope(scope, name, bindingType, loc);
  93. scope.var.add(name);
  94. this.maybeExportDefined(scope, name);
  95. if (scope.flags & _scopeflags.SCOPE_VAR) break;
  96. }
  97. }
  98. if (this.parser.inModule && scope.flags & _scopeflags.SCOPE_PROGRAM) {
  99. this.undefinedExports.delete(name);
  100. }
  101. }
  102. maybeExportDefined(scope, name) {
  103. if (this.parser.inModule && scope.flags & _scopeflags.SCOPE_PROGRAM) {
  104. this.undefinedExports.delete(name);
  105. }
  106. }
  107. checkRedeclarationInScope(scope, name, bindingType, loc) {
  108. if (this.isRedeclaredInScope(scope, name, bindingType)) {
  109. this.parser.raise(_parseError.Errors.VarRedeclaration, {
  110. at: loc,
  111. identifierName: name
  112. });
  113. }
  114. }
  115. isRedeclaredInScope(scope, name, bindingType) {
  116. if (!(bindingType & _scopeflags.BIND_KIND_VALUE)) return false;
  117. if (bindingType & _scopeflags.BIND_SCOPE_LEXICAL) {
  118. return scope.lexical.has(name) || scope.functions.has(name) || scope.var.has(name);
  119. }
  120. if (bindingType & _scopeflags.BIND_SCOPE_FUNCTION) {
  121. return scope.lexical.has(name) || !this.treatFunctionsAsVarInScope(scope) && scope.var.has(name);
  122. }
  123. return scope.lexical.has(name) && !(scope.flags & _scopeflags.SCOPE_SIMPLE_CATCH && scope.lexical.values().next().value === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.has(name);
  124. }
  125. checkLocalExport(id) {
  126. const {
  127. name
  128. } = id;
  129. const topLevelScope = this.scopeStack[0];
  130. if (!topLevelScope.lexical.has(name) && !topLevelScope.var.has(name) && !topLevelScope.functions.has(name)) {
  131. this.undefinedExports.set(name, id.loc.start);
  132. }
  133. }
  134. currentScope() {
  135. return this.scopeStack[this.scopeStack.length - 1];
  136. }
  137. currentVarScopeFlags() {
  138. for (let i = this.scopeStack.length - 1;; i--) {
  139. const {
  140. flags
  141. } = this.scopeStack[i];
  142. if (flags & _scopeflags.SCOPE_VAR) {
  143. return flags;
  144. }
  145. }
  146. }
  147. currentThisScopeFlags() {
  148. for (let i = this.scopeStack.length - 1;; i--) {
  149. const {
  150. flags
  151. } = this.scopeStack[i];
  152. if (flags & (_scopeflags.SCOPE_VAR | _scopeflags.SCOPE_CLASS) && !(flags & _scopeflags.SCOPE_ARROW)) {
  153. return flags;
  154. }
  155. }
  156. }
  157. }
  158. exports.default = ScopeHandler;
  159. //# sourceMappingURL=scope.js.map