scope.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /**
  2. * Copyright (c) 2009-2013 Jeremy Ashkenas
  3. *
  4. * Permission is hereby granted, free of charge, to any person
  5. * obtaining a copy of this software and associated documentation
  6. * files (the "Software"), to deal in the Software without
  7. * restriction, including without limitation the rights to use,
  8. * copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following
  11. * conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. * OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. */
  26. define(function(require, exports, module) {
  27. // Generated by CoffeeScript 1.6.3
  28. var Scope, extend, last, _ref;
  29. _ref = require('./helpers'), extend = _ref.extend, last = _ref.last;
  30. exports.Scope = Scope = (function() {
  31. Scope.root = null;
  32. function Scope(parent, expressions, method) {
  33. this.parent = parent;
  34. this.expressions = expressions;
  35. this.method = method;
  36. this.variables = [
  37. {
  38. name: 'arguments',
  39. type: 'arguments'
  40. }
  41. ];
  42. this.positions = {};
  43. if (!this.parent) {
  44. Scope.root = this;
  45. }
  46. }
  47. Scope.prototype.add = function(name, type, immediate) {
  48. if (this.shared && !immediate) {
  49. return this.parent.add(name, type, immediate);
  50. }
  51. if (Object.prototype.hasOwnProperty.call(this.positions, name)) {
  52. return this.variables[this.positions[name]].type = type;
  53. } else {
  54. return this.positions[name] = this.variables.push({
  55. name: name,
  56. type: type
  57. }) - 1;
  58. }
  59. };
  60. Scope.prototype.namedMethod = function() {
  61. var _ref1;
  62. if (((_ref1 = this.method) != null ? _ref1.name : void 0) || !this.parent) {
  63. return this.method;
  64. }
  65. return this.parent.namedMethod();
  66. };
  67. Scope.prototype.find = function(name) {
  68. if (this.check(name)) {
  69. return true;
  70. }
  71. this.add(name, 'var');
  72. return false;
  73. };
  74. Scope.prototype.parameter = function(name) {
  75. if (this.shared && this.parent.check(name, true)) {
  76. return;
  77. }
  78. return this.add(name, 'param');
  79. };
  80. Scope.prototype.check = function(name) {
  81. var _ref1;
  82. return !!(this.type(name) || ((_ref1 = this.parent) != null ? _ref1.check(name) : void 0));
  83. };
  84. Scope.prototype.temporary = function(name, index) {
  85. if (name.length > 1) {
  86. return '_' + name + (index > 1 ? index - 1 : '');
  87. } else {
  88. return '_' + (index + parseInt(name, 36)).toString(36).replace(/\d/g, 'a');
  89. }
  90. };
  91. Scope.prototype.type = function(name) {
  92. var v, _i, _len, _ref1;
  93. _ref1 = this.variables;
  94. for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
  95. v = _ref1[_i];
  96. if (v.name === name) {
  97. return v.type;
  98. }
  99. }
  100. return null;
  101. };
  102. Scope.prototype.freeVariable = function(name, reserve) {
  103. var index, temp;
  104. if (reserve == null) {
  105. reserve = true;
  106. }
  107. index = 0;
  108. while (this.check((temp = this.temporary(name, index)))) {
  109. index++;
  110. }
  111. if (reserve) {
  112. this.add(temp, 'var', true);
  113. }
  114. return temp;
  115. };
  116. Scope.prototype.assign = function(name, value) {
  117. this.add(name, {
  118. value: value,
  119. assigned: true
  120. }, true);
  121. return this.hasAssignments = true;
  122. };
  123. Scope.prototype.hasDeclarations = function() {
  124. return !!this.declaredVariables().length;
  125. };
  126. Scope.prototype.declaredVariables = function() {
  127. var realVars, tempVars, v, _i, _len, _ref1;
  128. realVars = [];
  129. tempVars = [];
  130. _ref1 = this.variables;
  131. for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
  132. v = _ref1[_i];
  133. if (v.type === 'var') {
  134. (v.name.charAt(0) === '_' ? tempVars : realVars).push(v.name);
  135. }
  136. }
  137. return realVars.sort().concat(tempVars.sort());
  138. };
  139. Scope.prototype.assignedVariables = function() {
  140. var v, _i, _len, _ref1, _results;
  141. _ref1 = this.variables;
  142. _results = [];
  143. for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
  144. v = _ref1[_i];
  145. if (v.type.assigned) {
  146. _results.push("" + v.name + " = " + v.type.value);
  147. }
  148. }
  149. return _results;
  150. };
  151. return Scope;
  152. })();
  153. });