symbol-table.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. var __classPrivateFieldSet = this && this.__classPrivateFieldSet || function (receiver, privateMap, value) {
  2. if (!privateMap.has(receiver)) {
  3. throw new TypeError("attempted to set private field on non-instance");
  4. }
  5. privateMap.set(receiver, value);
  6. return value;
  7. };
  8. var __classPrivateFieldGet = this && this.__classPrivateFieldGet || function (receiver, privateMap) {
  9. if (!privateMap.has(receiver)) {
  10. throw new TypeError("attempted to get private field on non-instance");
  11. }
  12. return privateMap.get(receiver);
  13. };
  14. var _hasEval;
  15. import { dict } from '@glimmer/util';
  16. import { isUpperCase } from './utils';
  17. export class SymbolTable {
  18. static top(locals, customizeComponentName) {
  19. return new ProgramSymbolTable(locals, customizeComponentName);
  20. }
  21. child(locals) {
  22. let symbols = locals.map(name => this.allocate(name));
  23. return new BlockSymbolTable(this, locals, symbols);
  24. }
  25. }
  26. export class ProgramSymbolTable extends SymbolTable {
  27. constructor(templateLocals, customizeComponentName) {
  28. super();
  29. this.templateLocals = templateLocals;
  30. this.customizeComponentName = customizeComponentName;
  31. this.symbols = [];
  32. this.upvars = [];
  33. this.size = 1;
  34. this.named = dict();
  35. this.blocks = dict();
  36. this.usedTemplateLocals = [];
  37. _hasEval.set(this, false);
  38. }
  39. getUsedTemplateLocals() {
  40. return this.usedTemplateLocals;
  41. }
  42. setHasEval() {
  43. __classPrivateFieldSet(this, _hasEval, true);
  44. }
  45. get hasEval() {
  46. return __classPrivateFieldGet(this, _hasEval);
  47. }
  48. has(name) {
  49. return this.templateLocals.indexOf(name) !== -1;
  50. }
  51. get(name) {
  52. let index = this.usedTemplateLocals.indexOf(name);
  53. if (index !== -1) {
  54. return [index, true];
  55. }
  56. index = this.usedTemplateLocals.length;
  57. this.usedTemplateLocals.push(name);
  58. return [index, true];
  59. }
  60. getLocalsMap() {
  61. return dict();
  62. }
  63. getEvalInfo() {
  64. let locals = this.getLocalsMap();
  65. return Object.keys(locals).map(symbol => locals[symbol]);
  66. }
  67. allocateFree(name, resolution) {
  68. // If the name in question is an uppercase (i.e. angle-bracket) component invocation, run
  69. // the optional `customizeComponentName` function provided to the precompiler.
  70. if (resolution.resolution() === 39
  71. /* GetFreeAsComponentHead */
  72. && resolution.isAngleBracket && isUpperCase(name)) {
  73. name = this.customizeComponentName(name);
  74. }
  75. let index = this.upvars.indexOf(name);
  76. if (index !== -1) {
  77. return index;
  78. }
  79. index = this.upvars.length;
  80. this.upvars.push(name);
  81. return index;
  82. }
  83. allocateNamed(name) {
  84. let named = this.named[name];
  85. if (!named) {
  86. named = this.named[name] = this.allocate(name);
  87. }
  88. return named;
  89. }
  90. allocateBlock(name) {
  91. if (name === 'inverse') {
  92. name = 'else';
  93. }
  94. let block = this.blocks[name];
  95. if (!block) {
  96. block = this.blocks[name] = this.allocate(`&${name}`);
  97. }
  98. return block;
  99. }
  100. allocate(identifier) {
  101. this.symbols.push(identifier);
  102. return this.size++;
  103. }
  104. }
  105. _hasEval = new WeakMap();
  106. export class BlockSymbolTable extends SymbolTable {
  107. constructor(parent, symbols, slots) {
  108. super();
  109. this.parent = parent;
  110. this.symbols = symbols;
  111. this.slots = slots;
  112. }
  113. get locals() {
  114. return this.symbols;
  115. }
  116. has(name) {
  117. return this.symbols.indexOf(name) !== -1 || this.parent.has(name);
  118. }
  119. get(name) {
  120. let slot = this.symbols.indexOf(name);
  121. return slot === -1 ? this.parent.get(name) : [this.slots[slot], false];
  122. }
  123. getLocalsMap() {
  124. let dict = this.parent.getLocalsMap();
  125. this.symbols.forEach(symbol => dict[symbol] = this.get(symbol)[0]);
  126. return dict;
  127. }
  128. getEvalInfo() {
  129. let locals = this.getLocalsMap();
  130. return Object.keys(locals).map(symbol => locals[symbol]);
  131. }
  132. setHasEval() {
  133. this.parent.setHasEval();
  134. }
  135. allocateFree(name, resolution) {
  136. return this.parent.allocateFree(name, resolution);
  137. }
  138. allocateNamed(name) {
  139. return this.parent.allocateNamed(name);
  140. }
  141. allocateBlock(name) {
  142. return this.parent.allocateBlock(name);
  143. }
  144. allocate(identifier) {
  145. return this.parent.allocate(identifier);
  146. }
  147. }
  148. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvc3ltYm9sLXRhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQSxTQUFTLElBQVQsUUFBcUIsZUFBckI7QUFHQSxTQUFTLFdBQVQsUUFBNEIsU0FBNUI7QUFFQSxPQUFNLE1BQWdCLFdBQWhCLENBQTJCO0FBQy9CLFNBQU8sR0FBUCxDQUNFLE1BREYsRUFFRSxzQkFGRixFQUVtRDtBQUVqRCxXQUFPLElBQUksa0JBQUosQ0FBdUIsTUFBdkIsRUFBK0Isc0JBQS9CLENBQVA7QUFDRDs7QUFlRCxFQUFBLEtBQUssQ0FBQyxNQUFELEVBQWlCO0FBQ3BCLFFBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFQLENBQVksSUFBRCxJQUFVLEtBQUssUUFBTCxDQUFjLElBQWQsQ0FBckIsQ0FBZDtBQUNBLFdBQU8sSUFBSSxnQkFBSixDQUFxQixJQUFyQixFQUEyQixNQUEzQixFQUFtQyxPQUFuQyxDQUFQO0FBQ0Q7O0FBeEI4QjtBQTJCakMsT0FBTSxNQUFPLGtCQUFQLFNBQWtDLFdBQWxDLENBQTZDO0FBQ2pELEVBQUEsV0FBQSxDQUNVLGNBRFYsRUFFVSxzQkFGVixFQUUyRDtBQUV6RDtBQUhRLFNBQUEsY0FBQSxHQUFBLGNBQUE7QUFDQSxTQUFBLHNCQUFBLEdBQUEsc0JBQUE7QUFLSCxTQUFBLE9BQUEsR0FBb0IsRUFBcEI7QUFDQSxTQUFBLE1BQUEsR0FBbUIsRUFBbkI7QUFFQyxTQUFBLElBQUEsR0FBTyxDQUFQO0FBQ0EsU0FBQSxLQUFBLEdBQVEsSUFBSSxFQUFaO0FBQ0EsU0FBQSxNQUFBLEdBQVMsSUFBSSxFQUFiO0FBQ0EsU0FBQSxrQkFBQSxHQUErQixFQUEvQjs7QUFFUixJQUFBLFFBQUEsQ0FBQSxHQUFBLENBQUEsSUFBQSxFQUFXLEtBQVg7QUFWQzs7QUFZRCxFQUFBLHFCQUFxQixHQUFBO0FBQ25CLFdBQU8sS0FBSyxrQkFB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LE1BQUwsQ0FBWSxVQUFaO0FBQ0Q7O0FBRUQsRUFBQSxZQUFZLENBQUMsSUFBRCxFQUFlLFVBQWYsRUFBa0Q7QUFDNUQsV0FBTyxLQUFLLE1BQUwsQ0FBWSxZQUFaLENBQXlCLElBQXpCLEVBQStCLFVBQS9CLENBQVA7QUFDRDs7QUFFRCxFQUFBLGFBQWEsQ0FBQyxJQUFELEVBQWE7QUFDeEIsV0FBTyxLQUFLLE1BQUwsQ0FBWSxhQUFaLENBQTBCLElBQTFCLENBQVA7QUFDRDs7QUFFRCxFQUFBLGFBQWEsQ0FBQyxJQUFELEVBQWE7QUFDeEIsV0FBTyxLQUFLLE1BQUwsQ0FBWSxhQUFaLENBQTBCLElBQTFCLENBQVA7QUFDRDs7QUFFRCxFQUFBLFFBQVEsQ0FBQyxVQUFELEVBQW1CO0FBQ3pCLFdBQU8sS0FBSyxNQUFMLENBQVksUUFBWixDQUFxQixVQUFyQixDQUFQO0FBQ0Q7O0FBL0M4QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvcmUsIERpY3QsIFNleHBPcGNvZGVzIH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBkaWN0IH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5cbmltcG9ydCB7IEFTVHYyIH0gZnJvbSAnLi4nO1xuaW1wb3J0IHsgaXNVcHBlckNhc2UgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN5bWJvbFRhYmxlIHtcbiAgc3RhdGljIHRvcChcbiAgICBsb2NhbHM6IHN0cmluZ1tdLFxuICAgIGN1c3RvbWl6ZUNvbXBvbmVudE5hbWU6IChpbnB1dDogc3RyaW5nKSA9PiBzdHJpbmdcbiAgKTogUHJvZ3JhbVN5bWJvbFRhYmxlIHtcbiAgICByZXR1cm4gbmV3IFByb2dyYW1TeW1ib2xUYWJsZShsb2NhbHMsIGN1c3RvbWl6ZUNvbXBvbmVudE5hbWUpO1xuICB9XG5cbiAgYWJzdHJhY3QgaGFzKG5hbWU6IHN0cmluZyk6IGJvb2xlYW47XG4gIGFic3RyYWN0IGdldChuYW1lOiBzdHJpbmcpOiBbc3ltYm9sOiBudW1iZXIsIGlzUm9vdDogYm9vbGVhbl07XG5cbiAgYWJzdHJhY3QgZ2V0TG9jYWxzTWFwKCk6IERpY3Q8bnVtYmVyPjtcbiAgYWJzdHJhY3QgZ2V0RXZhbEluZm8oKTogQ29yZS5FdmFsSW5mbztcblxuICBhYnN0cmFjdCBhbGxvY2F0ZUZyZWUobmFtZTogc3RyaW5nLCByZXNvbHV0aW9uOiBBU1R2Mi5GcmVlVmFyUmVzb2x1dGlvbik6IG51bWJlcjtcbiAgYWJzdHJhY3QgYWxsb2NhdGVOYW1lZChuYW1lOiBzdHJpbmcpOiBudW1iZXI7XG4gIGFic3RyYWN0IGFsbG9jYXRlQmxvY2sobmFtZTogc3RyaW5nKTogbnVtYmVyO1xuICBhYnN0cmFjdCBhbGxvY2F0ZShpZGVudGlmaWVyOiBzdHJpbmcpOiBudW1iZXI7XG5cbiAgYWJzdHJhY3Qgc2V0SGFzRXZhbCgpOiB2b2lkO1xuXG4gIGNoaWxkKGxvY2Fsczogc3RyaW5nW10pOiBCbG9ja1N5bWJvbFRhYmxlIHtcbiAgICBsZXQgc3ltYm9scyA9IGxvY2Fscy5tYXAoKG5hbWUpID0+IHRoaXMuYWxsb2NhdGUobmFtZSkpO1xuICAgIHJldHVybiBuZXcgQmxvY2tTeW1ib2xUYWJsZSh0aGlzLCBsb2NhbHMsIHN5bWJvbHMpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm9ncmFtU3ltYm9sVGFibGUgZXh0ZW5kcyBTeW1ib2xUYWJsZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdGVtcGxhdGVMb2NhbHM6IHN0cmluZ1tdLFxuICAgIHByaXZhdGUgY3VzdG9taXplQ29tcG9uZW50TmFtZTogKGlucHV0OiBzdHJpbmcpID0+IHN0cmluZ1xuICApIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcHVibGljIHN5bWJvbHM6IHN0cmluZ1tdID0gW107XG4gIHB1YmxpYyB1cHZhcnM6IHN0cmluZ1tdID0gW107XG5cbiAgcHJpdmF0ZSBzaXplID0gMTtcbiAgcHJpdmF0ZSBuYW1lZCA9IGRpY3Q8bnVtYmVyPigpO1xuICBwcml2YXRlIGJsb2NrcyA9IGRpY3Q8bnVtYmVyPigpO1xuICBwcml2YXRlIHVzZWRUZW1wbGF0ZUxvY2Fsczogc3RyaW5nW10gPSBbXTtcblxuICAjaGFzRXZhbCA9IGZhbHNlO1xuXG4gIGdldFVzZWRUZW1wbGF0ZUxvY2FscygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMudXNlZFRlbXBsYXRlTG9jYWxzO1xuICB9XG5cbiAgc2V0SGFzRXZhbCgpOiB2b2lkIHtcbiAgICB0aGlzLiNoYXNFdmFsID0gdHJ1ZTtcbiAgfVxuXG4gIGdldCBoYXNFdmFsKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLiNoYXNFdmFsO1xuICB9XG5cbiAgaGFzKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRlbXBsYXRlTG9jYWxzLmluZGV4T2YobmFtZSkgIT09IC0xO1xuICB9XG5cbiAgZ2V0KG5hbWU6IHN0cmluZyk6IFtudW1iZXIsIGJvb2xlYW5dIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLnVzZWRUZW1wbGF0ZUxvY2Fscy5pbmRleE9mKG5hbWUpO1xuXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgcmV0dXJuIFtpbmRleCwgdHJ1ZV07XG4gICAgfVxuXG4gICAgaW5kZXggPSB0aGlzLnVzZWRUZW1wbGF0ZUxvY2Fscy5sZW5ndGg7XG4gICAgdGhpcy51c2VkVGVtcGxhdGVMb2NhbHMucHVzaChuYW1lKTtcbiAgICByZXR1cm4gW2luZGV4LCB0cnVlXTtcbiAgfVxuXG4gIGdldExvY2Fsc01hcCgpOiBEaWN0PG51bWJlcj4ge1xuICAgIHJldHVybiBkaWN0KCk7XG4gIH1cblxuICBnZXRFdmFsSW5mbygpOiBDb3JlLkV2YWxJbmZvIHtcbiAgICBsZXQgbG9jYWxzID0gdGhpcy5nZXRMb2NhbHNNYXAoKTtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMobG9jYWxzKS5tYXAoKHN5bWJvbCkgPT4gbG9jYWxzW3N5bWJvbF0pO1xuICB9XG5cbiAgYWxsb2NhdGVGcmVlKG5hbWU6IHN0cmluZywgcmVzb2x1dGlvbjogQVNUdjIuRnJlZVZhclJlc29sdXRpb24pOiBudW1iZXIge1xuICAgIC8vIElmIHRoZSBuYW1lIGluIHF1ZXN0aW9uIGlzIGFuIHVwcGVyY2FzZSAoaS5lLiBhbmdsZS1icmFja2V0KSBjb21wb25lbnQgaW52b2NhdGlvbiwgcnVuXG4gICAgLy8gdGhlIG9wdGlvbmFsIGBjdXN0b21pemVDb21wb25lbnROYW1lYCBmdW5jdGlvbiBwcm92aWRlZCB0byB0aGUgcHJlY29tcGlsZXIuXG4gICAgaWYgKFxuICAgICAgcmVzb2x1dGlvbi5yZXNvbHV0aW9uKCkgPT09IFNleHBPcGNvZGVzLkdldEZyZWVBc0NvbXBvbmVudEhlYWQgJiZcbiAgICAgIHJlc29sdXRpb24uaXNBbmdsZUJyYWNrZXQgJiZcbiAgICAgIGlzVXBwZXJDYXNlKG5hbWUpXG4gICAgKSB7XG4gICAgICBuYW1lID0gdGhpcy5jdXN0b21pemVDb21wb25lbnROYW1lKG5hbWUpO1xuICAgIH1cblxuICAgIGxldCBpbmRleCA9IHRoaXMudXB2YXJzLmluZGV4T2YobmFtZSk7XG5cbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgaW5kZXggPSB0aGlzLnVwdmFycy5sZW5ndGg7XG4gICAgdGhpcy51cHZhcnMucHVzaChuYW1lKTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBhbGxvY2F0ZU5hbWVkKG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgbGV0IG5hbWVkID0gdGhpcy5uYW1lZFtuYW1lXTtcblxuICAgIGlmICghbmFtZWQpIHtcbiAgICAgIG5hbWVkID0gdGhpcy5uYW1lZFtuYW1lXSA9IHRoaXMuYWxsb2NhdGUobmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5hbWVkO1xuICB9XG5cbiAgYWxsb2NhdGVCbG9jayhuYW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGlmIChuYW1lID09PSAnaW52ZXJzZScpIHtcbiAgICAgIG5hbWUgPSAnZWxzZSc7XG4gICAgfVxuXG4gICAgbGV0IGJsb2NrID0gdGhpcy5ibG9ja3NbbmFtZV07XG5cbiAgICBpZiAoIWJsb2NrKSB7XG4gICAgICBibG9jayA9IHRoaXMuYmxvY2tzW25hbWVdID0gdGhpcy5hbGxvY2F0ZShgJiR7bmFtZX1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYmxvY2s7XG4gIH1cblxuICBhbGxvY2F0ZShpZGVudGlmaWVyOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHRoaXMuc3ltYm9scy5wdXNoKGlkZW50aWZpZXIpO1xuICAgIHJldHVybiB0aGlzLnNpemUrKztcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQmxvY2tTeW1ib2xUYWJsZSBleHRlbmRzIFN5bWJvbFRhYmxlIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBwYXJlbnQ6IFN5bWJvbFRhYmxlLCBwdWJsaWMgc3ltYm9sczogc3RyaW5nW10sIHB1YmxpYyBzbG90czogbnVtYmVyW10pIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgZ2V0IGxvY2FscygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuc3ltYm9scztcbiAgfVxuXG4gIGhhcyhuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zeW1ib2xzLmluZGV4T2YobmFtZSkgIT09IC0xIHx8IHRoaXMucGFyZW50LmhhcyhuYW1lKTtcbiAgfVxuXG4gIGdldChuYW1lOiBzdHJpbmcpOiBbbnVtYmVyLCBib29sZWFuXSB7XG4gICAgbGV0IHNsb3QgPSB0aGlzLnN5bWJvbHMuaW5kZXhPZihuYW1lKTtcbiAgICByZXR1cm4gc2xvdCA9PT0gLTEgPyB0aGlzLnBhcmVudC5nZXQobmFtZSkgOiBbdGhpcy5zbG90c1tzbG90XSwgZmFsc2VdO1xuICB9XG5cbiAgZ2V0TG9jYWxzTWFwKCk6IERpY3Q8bnVtYmVyPiB7XG4gICAgbGV0IGRpY3QgPSB0aGlzLnBhcmVudC5nZXRMb2NhbHNNYXAoKTtcbiAgICB0aGlzLnN5bWJvbHMuZm9yRWFjaCgoc3ltYm9sKSA9PiAoZGljdFtzeW1ib2xdID0gdGhpcy5nZXQoc3ltYm9sKVswXSkpO1xuICAgIHJldHVybiBkaWN0O1xuICB9XG5cbiAgZ2V0RXZhbEluZm8oKTogQ29yZS5FdmFsSW5mbyB7XG4gICAgbGV0IGxvY2FscyA9IHRoaXMuZ2V0TG9jYWxzTWFwKCk7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGxvY2FscykubWFwKChzeW1ib2wpID0+IGxvY2Fsc1tzeW1ib2xdKTtcbiAgfVxuXG4gIHNldEhhc0V2YWwoKTogdm9pZCB7XG4gICAgdGhpcy5wYXJlbnQuc2V0SGFzRXZhbCgpO1xuICB9XG5cbiAgYWxsb2NhdGVGcmVlKG5hbWU6IHN0cmluZywgcmVzb2x1dGlvbjogQVNUdjIuRnJlZVZhclJlc29sdXRpb24pOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnBhcmVudC5hbGxvY2F0ZUZyZWUobmFtZSwgcmVzb2x1dGlvbik7XG4gIH1cblxuICBhbGxvY2F0ZU5hbWVkKG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50LmFsbG9jYXRlTmFtZWQobmFtZSk7XG4gIH1cblxuICBhbGxvY2F0ZUJsb2NrKG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50LmFsbG9jYXRlQmxvY2sobmFtZSk7XG4gIH1cblxuICBhbGxvY2F0ZShpZGVudGlmaWVyOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnBhcmVudC5hbGxvY2F0ZShpZGVudGlmaWVyKTtcbiAgfVxufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==