public static void InvokeHandleMessage(this IDynamicInvoker instance, Message message)
        {
            var instype = instance.GetType();
            var msgtype = message.GetType();

            var key    = instype.Name + '!' + msgtype.Name;
            var action = _cache.ContainsKey(key) ? _cache[key] : null;

            if (action == null)
            {
                var method = instance.GetType()
                             .GetMethod("HandleMessage",
                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                        null,
                                        new[] { message.GetType() },
                                        null);
                var insparam = Expression.Parameter(typeof(IDynamicInvoker));
                var msgparam = Expression.Parameter(typeof(Message));
                var call     = Expression.Call(
                    Expression.Convert(insparam, instype),
                    method,
                    Expression.Convert(msgparam, msgtype));
                action      = Expression.Lambda <Action <IDynamicInvoker, Message> >(call, insparam, msgparam).Compile();
                _cache[key] = action;
            }
            action(instance, message);
        }
Example #2
0
 public InjectedServices(
     Stylesheet stylesheet,
     IDynamicInvoker dynamicInvoker,
     Func <object, ISelectable> asSelectable)
 {
     this.stylesheet     = stylesheet;
     this.dynamicInvoker = dynamicInvoker;
     this.asSelectable   = asSelectable;
 }
Example #3
0
        public ICompiledStylesheet Compile(
            Func <object, ISelectable> asSelectable,
            IEvaluator evaluator,
            IDynamicInvoker invoker,
            params ScriptParameter[] closure)
        {
            if (!ContainsScripts())
            {
                return(CompileSimple(asSelectable));
            }

            var compiled = CompiledScript.Compile(this, invoker, asSelectable);

            closure = compiled.Closure.Concat(closure ?? new ScriptParameter[0]).ToArray();
            var code = new StringBuilder();

            code.AppendLine($"(function ({string.Join(", ", closure.Select(c => c.Name))}) {{");
            code.AppendLine(compiled.Code);
            code.AppendLine("}).valueOf()");
            var func = invoker.Invoke(evaluator.Evaluate(code.ToString()), closure.Select(c => c.Value).ToArray());

            return(new ScriptStylesheet((root, arg) => invoker.Invoke(func, root, arg)));
        }
Example #4
0
 public CompiledScript CompileJs(
     Func <object, ISelectable> asSelectable,
     IDynamicInvoker invoker)
 {
     return(CompiledScript.Compile(this, invoker, asSelectable));
 }
Example #5
0
        internal static CompiledScript Compile(
            Stylesheet stylesheet,
            IDynamicInvoker dynamicInvoker,
            Func <object, ISelectable> asSelectable)
        {
            var code = new StringBuilder();

            code.AppendLine(
                @"return (function (__root__, args = {}) {

function __scriptPrivilege__(item) {
  return __svc__.GetScriptPrivilege(item);
}

function __isProxy__(item) {
  return '__isProxy__' in item && item['__isProxy__'];
}

function __wrap__(item) {
  if (__isProxy__(item)) {
    return item;
  }

  return __writable__(__svc__.AsScriptable(item));
}

__wrap__.readonly = function (item) {
  if (__isProxy__(item)) {
    return item;
  }

  return __readable__(__svc__.AsScriptable(item));
}

function __unwrap__(item) {
  if (__isProxy__(item)) {
    return item.element;
  }

  return item;
}

function __readable__(item) {
  if (__scriptPrivilege__(item) === 0) {
    return item;
  }

  return new Proxy(item, {
    has() {
      return true;
    },
    get(target, key) {
      if (typeof key !== 'string') {
        return undefined;
      }

      if (key === '__isProxy__') {
        return true;
      }

      return __readable__(target.Get(key));
    },
    set(target, key, value) { },
    deleteProperty(target, key) { }
  })
}

function __writable__(item) {
  const level = __scriptPrivilege__(item);
  if (level === 0) {
    return item;
  }

  if (typeof level === 'undefined') {
    level = __scriptPrivilege__(item);
  }

  return new Proxy(item, {
    has() { return true },
    get(target, key) {
      if (typeof key !== 'string') {
        return undefined;
      }

      if (key === '__isProxy__') {
        return true;
      }

      return __writable__(target.Get(key));
    },
    set(target, key, value) {
      if (level >= 2 && typeof key === 'string') {
        target.Set(key, value);
      }
    },
    deleteProperty(target, key) {
      if (level >= 3 && typeof key === 'string') {
        target.Delete(key);
      }
    }
  })
}

function __visit__(root, selector, callback, predicates = []) {
  __svc__.VisitScript(__unwrap__(root), selector, function (item) {
    const wrapped = __wrap__(item);
    callback.call(wrapped, wrapped);
  }, ...predicates.map(function (predicate) {
    return function (node) {
      return predicate.call(__wrap__.readonly(node));
    }
  }));
}

function __rule__(root, id) {
  __svc__.VisitRule(__unwrap__(root), id);
}

function __set__(root, key, value) {
  __svc__.Assign(__unwrap__(root), key, value);
}
");

            for (var i = 0; i < stylesheet.Declarations.Count; i++)
            {
                var id          = i.ToString();
                var declaration = stylesheet.Declarations[i];
                code.AppendLine(Serialize(id, declaration));
            }

            code.AppendLine("});");

            return(new CompiledScript(code.ToString(), new[]
            {
                new ScriptParameter("__svc__", new InjectedServices(stylesheet, dynamicInvoker, asSelectable)),
            }));
        }