public override PropertyTreeMetaObject BindAddChild(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     var result = definition.Apply(null, component, arguments);
     if (result == null)
         return Null;
     return CreateChild(result);
 }
        void FindActivationConstructor()
        {
            var tt = type.GetTypeInfo();

            if (tt.IsAbstract)
            {
                // Composable providers can be abstract
                if (type.IsProviderType() && tt.IsDefined(typeof(ComposableAttribute), false))
                {
                    var composeMember = App.GetProviderMember(type, "compose");
                    if (composeMember == null)
                    {
                        throw new NotImplementedException();
                    }

                    activationConstructor = ReflectedProviderFactoryDefinitionBase.Create(type, composeMember);
                }
            }
            else
            {
                MethodBase ctor = TypeHelper.FindActivationConstructor(type);
                if (ctor != null)
                {
                    activationConstructor = ReflectedPropertyTreeFactoryDefinition.Create(null, ctor);
                }
            }
        }
            private PropertyTreeMetaObject DoOperatorBind(PropertyTreeBinderImpl parent, PropertyTreeMetaObject target, PropertyTreeNavigator navigator, OperatorDefinition op)
            {
                OperatorDefinition addon = op;

                if (addon.DefaultParameter != null) {
                    Type itemType = ((PropertyTreeFactoryDefinition) addon).OutputType;
                    // TODO Use service activation (we have the output type)

                    var item = target.CreateChild(itemType);
                    var model = parent.Bind(item, navigator, null);
                    var args = new Dictionary<string, PropertyTreeMetaObject>
                    {
                        { addon.DefaultParameter.Name, model }
                    };

                    try {
                        target.BindAddChild(op, args);

                    } catch (Exception ex) {
                        if (ex.IsCriticalException())
                            throw;

                        parent.errors.BadAddChild(target.ComponentType, ex, navigator.FileLocation);
                    }

                } else {
                    // TODO The number and kinds of arguments are constrained.  This should probably
                    // be enforced within schema operator reflection (spec)

                    Action<IReadOnlyDictionary<string, PropertyTreeMetaObject>> func;
                    var children = NodeList.Create(SelectChildren(navigator));

                    switch (addon.OperatorType) {
                        case OperatorType.Add:
                            func = args => {
                                var child = target.BindAddChild(addon, args);

                                if (child.ShouldBindChildren) {
                                    parent.BindChildNodes(child, navigator, children);
                                }
                            };
                            break;

                        case OperatorType.Remove:
                            func = args => target.BindRemoveChild(addon, args);
                            break;

                        case OperatorType.Clear:
                        default:
                            func = args => target.BindClearChildren(addon, args);
                            break;
                    }

                    var services = parent.GetBasicServices(navigator);
                    var args2 = parent.ExtractParameterDictionary(op, target, services, children);
                    func(args2);
                }

                return target;
            }
        public override PropertyTreeMetaObject BindConstructor(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
        {
            var op = definition;
            object component = null;
            object parent = null;

            var value = op.Apply(component, parent, arguments);
            if (this.Parent == null)
                return Create(value);
            else
                return this.Parent.CreateChild(value);
        }
        internal void AddRange(OperatorDefinition owner, string ns, ParameterInfo[] parameters, bool extension)
        {
            foreach (var parm in parameters)
            {
                if (extension && parm.Position == 0)
                {
                    continue;
                }

                this.AddInternal(new ReflectedParameterDefinition(ns, parm));
            }
            this.FirstParameter = this.FirstOrDefault();
        }
        public CommonReflectionInfo(OperatorDefinition def, RoleAttribute attr, MethodBase method)
        {
            this.method = method;
            this.def = def;
            this.name = attr.ComputeName(method);

            var type = method.DeclaringType;
            if (type.IsGenericType && !type.IsGenericTypeDefinition)
                type = type.GetGenericTypeDefinition();

            this.ns = TypeHelper.GetNamespaceName(type);
            parameters = new PropertyDefinitionCollection();
            parameters.AddRange(def, ns, method.GetParameters(), method.IsExtension());
        }
        public CommonReflectionInfo(OperatorDefinition def, IRoleAttribute attr, MethodBase method)
        {
            this.method = method;
            this.name   = attr.ComputeName(method);

            var type = method.DeclaringType;

            if (type.GetTypeInfo().IsGenericType&& !type.GetTypeInfo().IsGenericTypeDefinition)
            {
                type = type.GetGenericTypeDefinition();
            }

            this.ns    = TypeHelper.GetNamespaceName(type);
            parameters = new PropertyDefinitionCollection();
            parameters.AddRange(def, ns, method.GetParameters(), method.IsExtension());
        }
        public override OperatorDefinition GetOperator(QualifiedName name, bool declaredOnly = false)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            OperatorDefinition result = this.Operators[name];

            if (result != null)
            {
                return(result);
            }

            if (declaredOnly)
            {
                return(null);
            }

            return(EnumerateOperators().FirstOrDefault(t => Utility.OrdinalIgnoreCaseQualifiedName.Equals(t.QualifiedName, name)));
        }
 public virtual void BindRemoveChild(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
 }
 public virtual PropertyTreeMetaObject BindConstructor(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     return this;
 }
 public virtual PropertyTreeMetaObject BindAddChild(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     return null;
 }
 internal Dictionary<string, PropertyTreeMetaObject> ExtractParameterDictionary(
     OperatorDefinition op,
     PropertyTreeMetaObject target,
     IServiceProvider serviceProvider,
     NodeList children)
 {
     return Parent.ExtractParameterDictionary(op, target, serviceProvider, children);
 }
 public void RequiredPropertiesMissing(IEnumerable<string> requiredMissing, OperatorDefinition op, FileLocation loc)
 {
     throw PropertyTreesFailure.RequiredPropertiesMissing(requiredMissing, op.ToString(), loc.LineNumber, loc.LinePosition);
 }
 public override PropertyTreeMetaObject BindConstructor(OperatorDefinition definition,
                                                        IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     if (definition.Parameters.Count != 0) {
         // TODO This is an error because we can't do construction inside template
         throw new NotImplementedException();
     }
     return this;
 }
 public override PropertyTreeMetaObject BindAddChild(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     AppendCommand(new AddChildCommand(definition, arguments));
     return FromInstanceType(definition.ReturnType);
 }
 public override PropertyTreeMetaObject BindConstructor(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     return new BuilderMetaObject(inner.BindConstructor(definition, arguments));
 }
 public override void BindRemoveChild(OperatorDefinition definition, IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     definition.Apply(null, component, arguments);
 }
        public Dictionary<string, PropertyTreeMetaObject> ExtractParameterDictionary(
            OperatorDefinition op,
            PropertyTreeMetaObject target,
            IServiceProvider serviceProvider,
            NodeList children)
        {
            // Named constructor arguments
            var duplicates = new HashSet<QualifiedName>();
            var mapped = new Dictionary<QualifiedName, PropertyTreeNavigator>();
            foreach (var child in children) {
                // Implicitly map default NS to real
                var impliedName = ImpliedName(child, target);

                if (duplicates.Contains(impliedName)) {
                    // Duplicates can't bind to parameters (only to param arrays)

                } else if (mapped.ContainsKey(impliedName)) {
                    // Detected a duplicate
                    duplicates.Add(impliedName);
                    mapped.Remove(impliedName);

                } else {
                    mapped.Add(impliedName, child);
                }
            }

            var args = new Dictionary<string, PropertyTreeMetaObject>(op.Parameters.Count);

            PropertyDefinition myParam = null;
            List<string> requiredMissing = new List<string>();

            foreach (PropertyDefinition p in op.Parameters) {
                // Fallback to empty ns
                PropertyTreeNavigator nav;
                QualifiedName impliedName = p.QualifiedName;
                if (p.QualifiedName.Namespace.IsDefault) {
                    impliedName = impliedName.ChangeNamespace(op.Namespace);
                }

                if (mapped.TryGetValue(impliedName, out nav)) {
                    // Binds a parameter required for activating an instance
                    // TODO Should we supply/use attributes from the parameter
                    // and/or corresponding property descriptor?

                    var childContext = target.CreateChild(p.PropertyType);
                    args[p.Name] = Bind(childContext, nav, serviceProvider);
                    children.Remove(nav);
                }
                else if (p.IsOptional) {
                    PropertyTreeMetaObject defaultValue;
                    if (p.DefaultValue == null)
                        defaultValue = PropertyTreeMetaObject.Create(p.PropertyType);
                    else
                        defaultValue = PropertyTreeMetaObject.Create(p.DefaultValue);
                    args[p.Name] = defaultValue;

                } else if (p.IsParamArray)
                    myParam = p;

                else if (TypeHelper.IsParameterRequired(p.PropertyType)) {
                    requiredMissing.Add(Utility.DisplayName(p.QualifiedName));
                }
            }

            if (requiredMissing.Count > 0)
                errors.RequiredPropertiesMissing(requiredMissing, op, FindFileLocation(serviceProvider));

            if (myParam == null && target.GetDefinition().DefaultProperty == null && duplicates.Any(t => target.SelectProperty(t) != null))
                errors.DuplicatePropertyName(duplicates, FindFileLocation(serviceProvider));

            // Try param array
            if (myParam != null) {
                var all = new List<object>();
                var elementType = myParam.PropertyType.GetElementType();
                foreach (var kvp in children) {

                    // Bind child nodes so tha latebound applies
                    var childrenList = NodeList.Create(PropertyTreeBinderImpl.SelectChildren(kvp));
                    var inline = BindChildNodes(PropertyTreeMetaObject.Create(elementType), kvp, childrenList);
                    var inlineVal = inline.Component;
                    all.Add(inlineVal);
                }

                children.Clear();
                var array = Array.CreateInstance(elementType, all.Count);
                ((System.Collections.ICollection) all).CopyTo(array, 0);
                args[myParam.Name] = PropertyTreeMetaObject.Create(array);
            }

            return args;
        }
 public AddChildCommand(OperatorDefinition definition,
                        IReadOnlyDictionary<string, PropertyTreeMetaObject> arguments)
 {
     this.definition = definition;
     this.arguments = arguments.ToDictionary(t => t.Key, t => t.Value.Component);
 }
        internal PropertyTreeMetaObject SetProviderMember(MemberInfo member)
        {
            if (member == null)
                return this;

            if (member.MemberType == MemberTypes.TypeInfo) {
                this.componentType = (Type) member;
                return this;

            } else if (member.MemberType == MemberTypes.Method) {
                this.factoryDefinition = ReflectedProviderFactoryDefinitionBase.Create(this.componentType, member);
                this.componentType = ((MethodInfo) member).ReturnType;
                return this;

            } else {
                var component = ((FieldInfo) member).GetValue(null);
                return this.Parent.CreateChild(component);
            }
        }