scope.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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 N = _interopRequireWildcard(require("../types"));
  8. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
  9. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  10. class Scope {
  11. constructor(flags) {
  12. this.var = [];
  13. this.lexical = [];
  14. this.functions = [];
  15. this.flags = flags;
  16. }
  17. }
  18. exports.Scope = Scope;
  19. class ScopeHandler {
  20. constructor(raise, inModule) {
  21. this.scopeStack = [];
  22. this.undefinedExports = new Map();
  23. this.undefinedPrivateNames = new Map();
  24. this.raise = raise;
  25. this.inModule = inModule;
  26. }
  27. get inFunction() {
  28. return (this.currentVarScope().flags & _scopeflags.SCOPE_FUNCTION) > 0;
  29. }
  30. get inGenerator() {
  31. return (this.currentVarScope().flags & _scopeflags.SCOPE_GENERATOR) > 0;
  32. }
  33. get inAsync() {
  34. for (let i = this.scopeStack.length - 1;; i--) {
  35. const scope = this.scopeStack[i];
  36. const isVarScope = scope.flags & _scopeflags.SCOPE_VAR;
  37. const isClassScope = scope.flags & _scopeflags.SCOPE_CLASS;
  38. if (isClassScope && !isVarScope) {
  39. return false;
  40. } else if (isVarScope) {
  41. return (scope.flags & _scopeflags.SCOPE_ASYNC) > 0;
  42. }
  43. }
  44. }
  45. get allowSuper() {
  46. return (this.currentThisScope().flags & _scopeflags.SCOPE_SUPER) > 0;
  47. }
  48. get allowDirectSuper() {
  49. return (this.currentThisScope().flags & _scopeflags.SCOPE_DIRECT_SUPER) > 0;
  50. }
  51. get inClass() {
  52. return (this.currentThisScope().flags & _scopeflags.SCOPE_CLASS) > 0;
  53. }
  54. get inNonArrowFunction() {
  55. return (this.currentThisScope().flags & _scopeflags.SCOPE_FUNCTION) > 0;
  56. }
  57. get treatFunctionsAsVar() {
  58. return this.treatFunctionsAsVarInScope(this.currentScope());
  59. }
  60. createScope(flags) {
  61. return new Scope(flags);
  62. }
  63. enter(flags) {
  64. this.scopeStack.push(this.createScope(flags));
  65. }
  66. exit() {
  67. this.scopeStack.pop();
  68. }
  69. treatFunctionsAsVarInScope(scope) {
  70. return !!(scope.flags & _scopeflags.SCOPE_FUNCTION || !this.inModule && scope.flags & _scopeflags.SCOPE_PROGRAM);
  71. }
  72. declareName(name, bindingType, pos) {
  73. let scope = this.currentScope();
  74. if (bindingType & _scopeflags.BIND_SCOPE_LEXICAL || bindingType & _scopeflags.BIND_SCOPE_FUNCTION) {
  75. this.checkRedeclarationInScope(scope, name, bindingType, pos);
  76. if (bindingType & _scopeflags.BIND_SCOPE_FUNCTION) {
  77. scope.functions.push(name);
  78. } else {
  79. scope.lexical.push(name);
  80. }
  81. if (bindingType & _scopeflags.BIND_SCOPE_LEXICAL) {
  82. this.maybeExportDefined(scope, name);
  83. }
  84. } else if (bindingType & _scopeflags.BIND_SCOPE_VAR) {
  85. for (let i = this.scopeStack.length - 1; i >= 0; --i) {
  86. scope = this.scopeStack[i];
  87. this.checkRedeclarationInScope(scope, name, bindingType, pos);
  88. scope.var.push(name);
  89. this.maybeExportDefined(scope, name);
  90. if (scope.flags & _scopeflags.SCOPE_VAR) break;
  91. }
  92. }
  93. if (this.inModule && scope.flags & _scopeflags.SCOPE_PROGRAM) {
  94. this.undefinedExports.delete(name);
  95. }
  96. }
  97. maybeExportDefined(scope, name) {
  98. if (this.inModule && scope.flags & _scopeflags.SCOPE_PROGRAM) {
  99. this.undefinedExports.delete(name);
  100. }
  101. }
  102. checkRedeclarationInScope(scope, name, bindingType, pos) {
  103. if (this.isRedeclaredInScope(scope, name, bindingType)) {
  104. this.raise(pos, `Identifier '${name}' has already been declared`);
  105. }
  106. }
  107. isRedeclaredInScope(scope, name, bindingType) {
  108. if (!(bindingType & _scopeflags.BIND_KIND_VALUE)) return false;
  109. if (bindingType & _scopeflags.BIND_SCOPE_LEXICAL) {
  110. return scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
  111. }
  112. if (bindingType & _scopeflags.BIND_SCOPE_FUNCTION) {
  113. return scope.lexical.indexOf(name) > -1 || !this.treatFunctionsAsVarInScope(scope) && scope.var.indexOf(name) > -1;
  114. }
  115. return scope.lexical.indexOf(name) > -1 && !(scope.flags & _scopeflags.SCOPE_SIMPLE_CATCH && scope.lexical[0] === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.indexOf(name) > -1;
  116. }
  117. checkLocalExport(id) {
  118. if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && this.scopeStack[0].var.indexOf(id.name) === -1 && this.scopeStack[0].functions.indexOf(id.name) === -1) {
  119. this.undefinedExports.set(id.name, id.start);
  120. }
  121. }
  122. currentScope() {
  123. return this.scopeStack[this.scopeStack.length - 1];
  124. }
  125. currentVarScope() {
  126. for (let i = this.scopeStack.length - 1;; i--) {
  127. const scope = this.scopeStack[i];
  128. if (scope.flags & _scopeflags.SCOPE_VAR) {
  129. return scope;
  130. }
  131. }
  132. }
  133. currentThisScope() {
  134. for (let i = this.scopeStack.length - 1;; i--) {
  135. const scope = this.scopeStack[i];
  136. if ((scope.flags & _scopeflags.SCOPE_VAR || scope.flags & _scopeflags.SCOPE_CLASS) && !(scope.flags & _scopeflags.SCOPE_ARROW)) {
  137. return scope;
  138. }
  139. }
  140. }
  141. }
  142. exports.default = ScopeHandler;