text: import { ComputedReferenceBlueprint, Meta } from '@glimmer/object-reference';
  import { EMPTY_CACHE } from './object';
  import { Blueprint } from './mixin';
  export class ComputedBlueprint extends Blueprint {
      constructor(accessor, deps = []) {
          super();
          this.metadata = {};
          this.accessor = accessor;
          this.deps = deps;
      }
      descriptor(_target, key, classMeta) {
          classMeta.addReferenceTypeFor(key, ComputedReferenceBlueprint(key, this.deps));
          classMeta.addPropertyMetadata(key, this.metadata);
          classMeta.addSlotFor(key);
          return new Computed(this.accessor);
      }
      property(...paths) {
          this.deps = paths.map(d => d.split('.'));
          return this;
      }
      meta(object) {
          this.metadata = object;
          return this;
      }
      volatile() {
          return this;
      }
  }
  class Computed {
      constructor(accessor) {
          this["5d90f84f-908e-4a42-9749-3d0f523c262c"] = true;
          this.accessor = accessor;
      }
      define(prototype, key, home) {
          Object.defineProperty(prototype, key, wrapAccessor(home, key, this.accessor));
      }
  }
  function wrapAccessor(home, accessorName, _desc) {
      let superDesc = getPropertyDescriptor(home, accessorName);
      let originalGet;
      let originalSet;
      let desc = {
          enumerable: true,
          configurable: true
      };
      let get = _desc.get;
      if (get && get.length > 0) {
          originalGet = function () {
              return get.call(this, accessorName);
          };
      } else {
          originalGet = _desc.get;
      }
      let set = _desc.set;
      if (set && set.length > 1) {
          originalSet = function (value) {
              return set.call(this, accessorName, value);
          };
      } else {
          originalSet = _desc.set;
      }
      let cacheGet = function () {
          if (Meta.exists(this)) {
              let slot = Meta.for(this).getSlots()[accessorName];
              if (slot !== EMPTY_CACHE) return slot;
          }
          return originalGet.call(this);
      };
      let cacheSet;
      if (originalSet) {
          cacheSet = function (value) {
              let meta = Meta.for(this);
              let slots = meta.getSlots();
              let ret = originalSet.call(this, value);
              if (ret !== undefined) {
                  slots[accessorName] = ret;
              }
          };
      } else {
          cacheSet = function (value) {
              let meta = Meta.for(this);
              let slots = meta.getSlots();
              if (value !== undefined) slots[accessorName] = value;
          };
      }
      if (!superDesc || 'value' in superDesc) {
          desc.get = cacheGet;
          desc.set = cacheSet;
          return desc;
      }
      desc.get = function () {
          let lastSuper = this._super;
          this._super = function () {
              return superDesc.get.call(this);
          };
          try {
              return cacheGet.call(this);
          } finally {
              this._super = lastSuper;
          }
      };
      desc.set = function (val) {
          let lastSuper = this._super;
          this._super = function () {
              return superDesc.set.call(this, val);
          };
          try {
              return cacheSet.call(this, val);
          } finally {
              this._super = lastSuper;
          }
      };
      return desc;
  }
  function getPropertyDescriptor(subject, name) {
      let pd = Object.getOwnPropertyDescriptor(subject, name);
      let proto = Object.getPrototypeOf(subject);
      while (typeof pd === 'undefined' && proto !== null) {
          pd = Object.getOwnPropertyDescriptor(proto, name);
          proto = Object.getPrototypeOf(proto);
      }
      return pd;
  }
  export function computed(...args) {
      let last = args.pop();
      let deps = args;
      if (typeof last === 'function') {
          return new ComputedBlueprint({
              get: last
          }).property(...deps);
      } else if (typeof last === 'object') {
          return new ComputedBlueprint(last).property(...deps);
      } else {
          throw new TypeError("computed expects a function or an object as last argument");
      }
  }
  export function observer(..._args) {}