reflect.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Useful compiler idioms.
  16. *
  17. * @author johnlenz@google.com (John Lenz)
  18. */
  19. goog.provide('goog.reflect');
  20. /**
  21. * Syntax for object literal casts.
  22. * @see http://go/jscompiler-renaming
  23. * @see https://goo.gl/CRs09P
  24. *
  25. * Use this if you have an object literal whose keys need to have the same names
  26. * as the properties of some class even after they are renamed by the compiler.
  27. *
  28. * @param {!Function} type Type to cast to.
  29. * @param {Object} object Object literal to cast.
  30. * @return {Object} The object literal.
  31. */
  32. goog.reflect.object = function(type, object) {
  33. return object;
  34. };
  35. /**
  36. * Syntax for renaming property strings.
  37. * @see http://go/jscompiler-renaming
  38. * @see https://goo.gl/CRs09P
  39. *
  40. * Use this if you have an need to access a property as a string, but want
  41. * to also have the property renamed by the compiler. In contrast to
  42. * goog.reflect.object, this method takes an instance of an object.
  43. *
  44. * Properties must be simple names (not qualified names).
  45. *
  46. * @param {string} prop Name of the property
  47. * @param {!Object} object Instance of the object whose type will be used
  48. * for renaming
  49. * @return {string} The renamed property.
  50. */
  51. goog.reflect.objectProperty = function(prop, object) {
  52. return prop;
  53. };
  54. /**
  55. * To assert to the compiler that an operation is needed when it would
  56. * otherwise be stripped. For example:
  57. * <code>
  58. * // Force a layout
  59. * goog.reflect.sinkValue(dialog.offsetHeight);
  60. * </code>
  61. * @param {T} x
  62. * @return {T}
  63. * @template T
  64. */
  65. goog.reflect.sinkValue = function(x) {
  66. goog.reflect.sinkValue[' '](x);
  67. return x;
  68. };
  69. /**
  70. * The compiler should optimize this function away iff no one ever uses
  71. * goog.reflect.sinkValue.
  72. */
  73. goog.reflect.sinkValue[' '] = goog.nullFunction;
  74. /**
  75. * Check if a property can be accessed without throwing an exception.
  76. * @param {Object} obj The owner of the property.
  77. * @param {string} prop The property name.
  78. * @return {boolean} Whether the property is accessible. Will also return true
  79. * if obj is null.
  80. */
  81. goog.reflect.canAccessProperty = function(obj, prop) {
  82. try {
  83. goog.reflect.sinkValue(obj[prop]);
  84. return true;
  85. } catch (e) {
  86. }
  87. return false;
  88. };
  89. /**
  90. * Retrieves a value from a cache given a key. The compiler provides special
  91. * consideration for this call such that it is generally considered side-effect
  92. * free. However, if the {@code opt_keyFn} or {@code valueFn} have side-effects
  93. * then the entire call is considered to have side-effects.
  94. *
  95. * Conventionally storing the value on the cache would be considered a
  96. * side-effect and preclude unused calls from being pruned, ie. even if
  97. * the value was never used, it would still always be stored in the cache.
  98. *
  99. * Providing a side-effect free {@code valueFn} and {@code opt_keyFn}
  100. * allows unused calls to {@code goog.reflect.cache} to be pruned.
  101. *
  102. * @param {!Object<K, V>} cacheObj The object that contains the cached values.
  103. * @param {?} key The key to lookup in the cache. If it is not string or number
  104. * then a {@code opt_keyFn} should be provided. The key is also used as the
  105. * parameter to the {@code valueFn}.
  106. * @param {function(?):V} valueFn The value provider to use to calculate the
  107. * value to store in the cache. This function should be side-effect free
  108. * to take advantage of the optimization.
  109. * @param {function(?):K=} opt_keyFn The key provider to determine the cache
  110. * map key. This should be used if the given key is not a string or number.
  111. * If not provided then the given key is used. This function should be
  112. * side-effect free to take advantage of the optimization.
  113. * @return {V} The cached or calculated value.
  114. * @template K
  115. * @template V
  116. */
  117. goog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) {
  118. var storedKey = opt_keyFn ? opt_keyFn(key) : key;
  119. if (Object.prototype.hasOwnProperty.call(cacheObj, storedKey)) {
  120. return cacheObj[storedKey];
  121. }
  122. return (cacheObj[storedKey] = valueFn(key));
  123. };