Exemple #1
0
        public override IEnumerable <CodeComponent <TAttribute> > GetComponents <TAttribute>()
        {
            if (Items != null)
            {
                foreach (PObject item in Items)
                {
                    if (!item.HasAttribute <TAttribute>())
                    {
                        continue;
                    }

                    var attr      = item.GetAttribute <TAttribute>();
                    var component = new CodeComponent <TAttribute>(item, attr);
                    var stack     = new Stack <CodeComponent <TAttribute> >(new[] { component });

                    while (stack.Count > 0)
                    {
                        var cc = stack.Pop();

                        if (NodeIterating || (!NodeIterating && cc.Depth == 0))
                        {
                            yield return(cc);
                        }

                        if (cc.ElementType == CodeComponentType.Instance)
                        {
                            // 클래스 인경우
                            Type eType  = cc.Element.GetType();
                            var  ignore = eType.GetAttribute <DXIgnoreAttribute>();

                            foreach (PropertyInfo pi in eType
                                     .GetProperties()
                                     .Where(pi => pi.HasAttribute <TAttribute>()))
                            {
                                if (ignore != null && ignore.PropertyNames.Contains(pi.Name))
                                {
                                    continue;
                                }

                                var pAttr     = pi.GetAttribute <TAttribute>();
                                var pComponet = new CodeComponent <TAttribute>(pi, pAttr)
                                {
                                    Depth = cc.Depth + 1
                                };

                                cc.Add(pComponet);
                                stack.Push(pComponet);
                            }
                        }
                        else
                        {
                            var pi = cc.Element as PropertyInfo;

                            // 배열인 경우
                            if (pi.CanCastingTo <IEnumerable <PObject> >())
                            {
                                var list = (IEnumerable <PObject>)pi.GetValue(cc.Parent.Element);

                                if (list == null)
                                {
                                    continue;
                                }

                                // 스택 처리 순서와 코드 구성 순서를 맞추기위해 뒤집어야함
                                foreach (var obj in list.Reverse())
                                {
                                    var oAttr      = obj.GetAttribute <TAttribute>();
                                    var oComponent = new CodeComponent <TAttribute>(obj, oAttr)
                                    {
                                        Depth = cc.Depth + 1
                                    };

                                    cc.Add(oComponent);
                                    stack.Push(oComponent);
                                }
                            }
                            else if (pi.CanCastingTo <PObject>())
                            {
                                var obj = pi.GetValue(cc.Parent.Element);

                                if (obj == null)
                                {
                                    continue;
                                }

                                var oAttr      = obj.GetAttribute <TAttribute>();
                                var oComponent = new CodeComponent <TAttribute>(obj, oAttr)
                                {
                                    Depth = cc.Depth + 1
                                };

                                cc.Add(oComponent);
                                stack.Push(oComponent);
                            }
                        }
                    }
                }
            }
        }
Exemple #2
0
 public int GetHashCode(CodeComponent <TAttribute> obj)
 {
     return(obj.Element.GetHashCode());
 }
Exemple #3
0
 public bool Equals(CodeComponent <TAttribute> x, CodeComponent <TAttribute> y)
 {
     return(x.Element.Equals(y.Element));
 }
Exemple #4
0
        protected override IEnumerable <string> OnGenerate(IEnumerable <CodeComponent <CSharpCodeMapAttribute> > components)
        {
            var items = components.ToArray();
            CodeComponent <CSharpCodeMapAttribute> root = items.FirstOrDefault();

            // Trigger Hosts
            CodeComponent <CSharpCodeMapAttribute>[] triggers = items
                                                                .Where(cc => cc.Depth == 0)
                                                                .SelectMany(item => item.Children)
                                                                .Where(item => item.Element is PTrigger)
                                                                .Distinct(new CodeComponentComparer <CSharpCodeMapAttribute>())
                                                                .ToArray();

            //// Trigger Hosts
            //CodeComponent<CSharpCodeMapAttribute>[] triggers = items
            //    .Where(cc => cc.Depth == 0)
            //    .SelectMany(item => item.Children)
            //    .Distinct(new CodeComponentComparer<CSharpCodeMapAttribute>())
            //    .ToArray();

            // Event Handle
            var eventHandlerBuilder = new StringBuilder();

            foreach (var trigger in triggers)
            {
                var    result       = this.Mapper.Build(trigger.Element, trigger.Attribute.MappingCode);
                string source       = result.Source;
                string callbackName = Mapper.MappingProvider.GetEventCallbackName(trigger.Element as PTrigger);

                source = source.Replace("{EventCallback}", callbackName);

                eventHandlerBuilder.AppendLine(source);
            }

            yield return(eventHandlerBuilder.ToString());

            // Callback
            foreach (var trigger in triggers)
            {
                string callbackSource = GenerateCallback(trigger.Element as PTrigger);
                string code           = "";

                if (trigger.HasChildren)
                {
                    // 지역 변수 컨테이너
                    var localVariableContainer = new NameContainer();

                    code = CreateScope(trigger.Children.ToArray(), localVariableContainer, true);
                }

                yield return(callbackSource.Replace("{Code}", code));
            }

            // CreateScope (Recursive)
            string CreateScope(CodeComponent <CSharpCodeMapAttribute>[] scopeComponents, NameContainer localVariableContainer, bool isCodeBlock = false)
            {
                var scopeBuilder = new IndentStringBuilder();
                var stack        = new Stack <CodeComponent <CSharpCodeMapAttribute> >(scopeComponents);

                if (!isCodeBlock)
                {
                    scopeBuilder.AppendLine();
                    scopeBuilder.AppendLine("{");
                }

                while (stack.Count > 0)
                {
                    var cc = stack.Pop();

                    var mappingResult = this.Mapper.Build(cc.Element, cc.Attribute.MappingCode);
                    var sourceBuilder = new IndentStringBuilder(mappingResult.Source);

                    if (cc.Element is PBinderHost host)
                    {
                        foreach (DXToken token in mappingResult.Errors)
                        {
                            switch (token.Token)
                            {
                            case "Scope":
                            {
                                if (!token.IsIndexed)
                                {
                                    continue;
                                }

                                int index = int.Parse(token.Parameter) - 1;

                                var scopeBinder          = host[BindOptions.Output].ElementAt(index) as PBinder;
                                var childScopeComponents = scopeBinder.Items
                                                           .Select(item => item.Host as PBinderHost)
                                                           .Distinct()
                                                           .Select(childHost => new CodeComponent <CSharpCodeMapAttribute>(
                                                                       childHost, childHost.GetAttribute <CSharpCodeMapAttribute>()))
                                                           .ToArray();

                                sourceBuilder.Replace(
                                    token.OriginalSource,
                                    CreateScope(childScopeComponents, localVariableContainer));

                                break;
                            }

                            case "Line":
                            {
                                if (!token.IsIndexed)
                                {
                                    continue;
                                }

                                int index = int.Parse(token.Parameter) - 1;

                                var paramBinder = host[BindOptions.Parameter].ElementAt(index) as PBinder;

                                ProcessBinderValue(sourceBuilder, token, paramBinder);
                                break;
                            }

                            default:
                                break;
                            }
                        }
                    }

                    scopeBuilder.AppendBlock(sourceBuilder.ToString(), 1);
                    scopeBuilder.AppendLine();
                }

                if (!isCodeBlock)
                {
                    scopeBuilder.AppendLine("}");
                }

                return(scopeBuilder.ToString());
            }

            //string CreateLambda()

            void ProcessBinderValue(IndentStringBuilder sourceBuilder, DXToken token, PBinder binder)
            {
                string valueLine = null;

                // 직접 입력
                if (binder.IsDirectValue)
                {
                    object value = binder.DirectValue;

                    valueLine = this.Mapper.MappingProvider.GetValueLine(value, true);
                }
                // 연결됨
                else if (binder.Items.Count == 1)
                {
                    var paramOutputHost = binder.Items[0].Host;

                    var attr = paramOutputHost.GetAttribute <CSharpCodeMapAttribute>();

                    if (paramOutputHost is PTrigger)
                    {
                        valueLine = "sender";
                    }
                    else
                    {
                        valueLine = this.Mapper.Build(paramOutputHost, attr.MappingCode).Source;
                    }
                }
                else
                {
                    // Error
                }

                if (valueLine != null)
                {
                    int idx = sourceBuilder.IndexOf(token.OriginalSource);

                    // 토큰 부분 제거
                    sourceBuilder.Replace(token.OriginalSource, "");

                    sourceBuilder.Insert(idx, valueLine);
                }
            }
        }
 private XmlElement CreateElement(XmlDocument doc, CodeComponent <WPFAttribute> component)
 {
     return(CreateElement(doc, component.Attribute.Name, component));
 }
        protected override IEnumerable <string> OnGenerate(IEnumerable <CodeComponent <WPFAttribute> > components)
        {
            var items = components.ToArray();
            CodeComponent <WPFAttribute> root = items.FirstOrDefault();

            // 이름이 설정되지 않은경우 생성해줌
            ImagePatch(items);
            NamingPatch(items);
            NamespacePatch(items);

            if (root.Element is PPage page)
            {
                this.NameContainer[page] = page.GetPageName();
            }

            var doc = new XmlDocument();

            XmlElement rootElement = CreateElement(doc, root);

            rootElement.SetAttribute("xmlns", XMLNS);

            // 네임스페이스 선언
            foreach (var namespaceKv in this.XamlNamespaceContainer)
            {
                rootElement.SetAttribute($"xmlns:{namespaceKv.Value}", namespaceKv.Key);
            }

            SetXamlName(rootElement, root);

            var comQueue = new Queue <CodeComponent <WPFAttribute> >(new[] { root });
            var xmlQueue = new Queue <XmlElement>(new[] { rootElement });

            while (comQueue.Count > 0)
            {
                var com = comQueue.Dequeue();
                var xml = xmlQueue.Dequeue();

                if (com.HasChildren)
                {
                    var content = com.GetContentComponent();

                    // property
                    foreach (var child in com.Children
                             .Where(c => c.ElementType == CodeComponentType.Property))
                    {
                        if (content == child)
                        {
                            continue;
                        }

                        var pi = child.Element as PropertyInfo;

                        //if (pi.IsDefaultDependencyProperty(child.Parent.Element as PObject))
                        //    continue;

                        object value = pi.GetValue(child.Parent.Element);

                        if (pi.CanCastingTo <IEnumerable <PObject> >())
                        {
                            XmlElement lstXml = CreateElement(doc,
                                                              $"{child.Parent.Attribute.Name}.{child.Attribute.Name}", child.Parent);

                            xml.AppendChild(lstXml);

                            if (child.HasChildren)
                            {
                                foreach (var item in child.Children?.Reverse())
                                {
                                    XmlElement childXml = CreateElement(doc, item);
                                    lstXml.AppendChild(childXml);

                                    SetXamlName(childXml, item);

                                    comQueue.Enqueue(item);
                                    xmlQueue.Enqueue(childXml);
                                }
                            }
                        }
                        else
                        {
                            bool isContinue = false;

                            // Null Reference
                            isContinue |= (value == null);

                            // Auto Size Pass
                            isContinue |= (value is double && double.IsNaN((double)value));

                            if (!isContinue)
                            {
                                if (child.HasResource)
                                {
                                    xml.SetAttribute(
                                        child.Attribute.Name,
                                        GetResourceName(child.ResourceType.Value, value.ToString()));
                                }
                                else
                                {
                                    xml.SetAttribute(
                                        child.Attribute.Name,
                                        ValueToXamlInline(value));
                                }
                            }
                        }
                    }

                    // Content
                    if (content != null && content.HasChildren)
                    {
                        var pi = content.Element as PropertyInfo;

                        if (pi.CanCastingTo <IEnumerable <PObject> >())
                        {
                            foreach (var item in content.Children?.Reverse())
                            {
                                XmlElement contentXml = CreateElement(doc, item);
                                xml.AppendChild(contentXml);

                                SetXamlName(contentXml, item);

                                comQueue.Enqueue(item);
                                xmlQueue.Enqueue(contentXml);
                            }
                        }
                        else if (pi.CanCastingTo <PObject>())
                        {
                            var        contentItem = content.Children[0];
                            XmlElement contentXml  = CreateElement(doc, contentItem);
                            xml.AppendChild(contentXml);

                            SetXamlName(contentXml, contentItem);

                            comQueue.Enqueue(contentItem);
                            xmlQueue.Enqueue(contentXml);
                        }
                    }
                }
            }

            doc.AppendChild(rootElement);

            // 인덴트 처리
            using (var ms = new MemoryStream())
            {
                using (var writer = new XmlTextWriter(ms, new UTF8Encoding(false)))
                {
                    writer.Formatting = Formatting.Indented;
                    doc.Save(writer);

                    yield return(Encoding.UTF8.GetString(ms.ToArray()));
                }
            }
        }
Exemple #7
0
        private string XamlGenerate(IEnumerable <CodeComponent <XFormsAttribute> > components)
        {
            var items = components.ToArray();
            CodeComponent <XFormsAttribute> root = items[0];
            string pageName = null;

            if (root.Element is PPage page)
            {
                pageName = page.GetPageName();
            }

            // 루트페이지는 항상 이름(파일, 클래스 이름)이 설정되어있어야 함
            if (pageName == null)
            {
                throw new ArgumentException();
            }

            var doc = new XmlDocument();
            var dec = doc.CreateXmlDeclaration("1.0", "utf-8", null);

            // 노드
            XmlElement rootElement = doc.CreateElement(root.Attribute.Name);

            rootElement.SetAttribute("xmlns", XMLNS);
            rootElement.SetAttribute("xmlns:x", XMLNSX);
            rootElement.SetAttribute("xmlns:local", $"clr-namespace:{this.Manifest.RootNamespace}");
            rootElement.SetAttribute("Class", XMLNSX, $"{this.Manifest.RootNamespace}.{pageName}");

            SetXamlName(rootElement, root);

            var comQueue = new Queue <CodeComponent <XFormsAttribute> >(new[] { root });
            var xmlQueue = new Queue <XmlElement>(new[] { rootElement });

            while (comQueue.Count > 0)
            {
                var com = comQueue.Dequeue();
                var xml = xmlQueue.Dequeue();

                if (com.HasChildren)
                {
                    var content = com.GetContentComponent();

                    // property
                    foreach (var child in com.Children
                             .Where(c => c.ElementType == CodeComponentType.Property))
                    {
                        if (content == child)
                        {
                            continue;
                        }

                        var pi = child.Element as PropertyInfo;

                        if (pi.IsDefaultDependencyProperty(child.Parent.Element as PObject))
                        {
                            continue;
                        }

                        object value = pi.GetValue(child.Parent.Element);

                        if (pi.CanCastingTo <IEnumerable <PObject> >())
                        {
                            var lstXml = doc.CreateElement(
                                $"{child.Parent.Attribute.Name}.{child.Attribute.Name}");

                            xml.AppendChild(lstXml);

                            if (child.HasChildren)
                            {
                                foreach (var item in child.Children?.Reverse())
                                {
                                    var childXml = doc.CreateElement(item.Attribute.Name);
                                    lstXml.AppendChild(childXml);

                                    SetXamlName(childXml, item);

                                    comQueue.Enqueue(item);
                                    xmlQueue.Enqueue(childXml);
                                }
                            }
                        }
                        else
                        {
                            bool isContinue = false;

                            // Null Reference
                            isContinue |= (value == null);

                            // Auto Size Pass
                            isContinue |= (value is double && double.IsNaN((double)value));

                            if (!isContinue)
                            {
                                xml.SetAttribute(
                                    child.Attribute.Name,
                                    ValueToXamlInline(value));
                            }
                        }
                    }

                    // Content
                    if (content != null && content.HasChildren)
                    {
                        var pi = content.Element as PropertyInfo;

                        if (pi.CanCastingTo <IEnumerable <PObject> >())
                        {
                            foreach (var item in content.Children?.Reverse())
                            {
                                var contentXml = doc.CreateElement(item.Attribute.Name);
                                xml.AppendChild(contentXml);

                                SetXamlName(contentXml, item);

                                comQueue.Enqueue(item);
                                xmlQueue.Enqueue(contentXml);
                            }
                        }
                        else if (pi.CanCastingTo <PObject>())
                        {
                            var contentItem = content.Children[0];
                            var contentXml  = doc.CreateElement(contentItem.Attribute.Name);
                            xml.AppendChild(contentXml);

                            SetXamlName(contentXml, contentItem);

                            comQueue.Enqueue(contentItem);
                            xmlQueue.Enqueue(contentXml);
                        }
                    }
                }
            }

            doc.AppendChild(dec);
            doc.AppendChild(rootElement);

            // 인덴트 처리
            using (var ms = new MemoryStream())
            {
                using (var writer = new XmlTextWriter(ms, new UTF8Encoding(false)))
                {
                    writer.Formatting = Formatting.Indented;
                    doc.Save(writer);

                    return(Encoding.UTF8.GetString(ms.ToArray()));
                }
            }
        }
Exemple #8
0
        public override IEnumerable <CodeComponent <TAttribute> > GetComponents <TAttribute>()
        {
            if (Items != null)
            {
                foreach (PObject item in Items
                         .SelectMany(host => host.Items.GetExpressions())
                         .Select(e => e.Output.Host)
                         .Distinct())
                {
                    if (!item.HasAttribute <TAttribute>())
                    {
                        continue;
                    }

                    var attr      = item.GetAttribute <TAttribute>();
                    var component = new CodeComponent <TAttribute>(item, attr);
                    var stack     = new Stack <CodeComponent <TAttribute> >(new[] { component });

                    component.ElementType = CodeComponentType.Node;

                    while (stack.Count > 0)
                    {
                        var cc = stack.Pop();

                        //if (NodeIterating || (!NodeIterating && cc.Depth == 0))
                        //    yield return cc;

                        if (cc.ElementType == CodeComponentType.Node)
                        {
                            var host      = cc.Element as PBinderHost;
                            var zeroNodes = new List <PBinderHost>();

                            var childStack = new Stack <PBinderHost>(new[] { host });

                            // 호스트와 연결된 모든 노드를 BFS알고리즘을 사용하여 가져오고
                            // 생성된 Output Binder의 갯수가 1개인 것만 노드로 인정함
                            // 갯수가 2개이상인 노드에서 멈춤 (2개이상은 스코프가 분기된다고 가정)
                            while (childStack.Count > 0)
                            {
                                PBinderHost child = childStack.Pop();

                                foreach (PBinderHost childNode in BinderHelper.FindHostNodes(child, BindOptions.Output, 0))
                                {
                                    if (childNode[BindOptions.Output].Count() == 1 && childNode is PTrigger == false)
                                    {
                                        childStack.Push(childNode);
                                    }

                                    zeroNodes.Add(childNode);
                                }
                            }

                            foreach (PBinderHost zeroNode in zeroNodes)
                            {
                                var childComponent = new CodeComponent <TAttribute>(
                                    zeroNode,
                                    zeroNode.GetAttribute <TAttribute>())
                                {
                                    Depth       = cc.Depth + 1,
                                    ElementType = CodeComponentType.Node
                                };

                                cc.Add(childComponent);

                                if (zeroNode[BindOptions.Output].Count() > 1 || zeroNode is PTrigger)
                                {
                                    stack.Push(childComponent);
                                }
                            }
                        }
                    }

                    yield return(component);
                }
            }
        }