コード例 #1
0
        private bool BuildProperty(DXToken token, object obj, StringBuilder source)
        {
            Type objType = obj.GetType();

            if (!token.HasParameter)
            {
                return(false);
            }

            // 클래스가 아닌경우
            if (!obj.GetType().IsClass)
            {
                return(false);
            }

            PropertyInfo pi = objType.GetProperty(token.Parameter);

            if (pi == null)
            {
                return(false);
            }

            // 속성에서 실제값을 가져옴
            object value     = pi.GetValue(obj);
            string valueLine = null;

            // 속성값이 바인더인 경우
            if (value is PBinder binder)
            {
                valueLine = this.BuildBinder(binder);
            }
            else if (value is DependencyProperty prop)
            {
                PropertyInfo targetPi = prop.OwnerType.GetProperty(prop.Name);

                valueLine = this.MappingProvider.GetValueLine(targetPi);
            }
            else
            {
                valueLine = this.MappingProvider.GetValueLine(value);
            }

            if (valueLine != null)
            {
                // source 토큰 치환
                foreach (DXToken innerToken in DXToken.Parse(valueLine))
                {
                    source.Replace(innerToken.OriginalSource, "");
                }

                source.Replace(
                    token.OriginalSource,
                    valueLine);
            }

            return(true);
        }
コード例 #2
0
        private DXMappingResult buildImpl(BuildStackTrace trace, object obj, string source)
        {
            // trace capture
            trace.Capture(obj, source);

            var result        = new DXMappingResult();
            var sourceBuilder = new StringBuilder(source);

            // 이벤트 핸들러 연결 코드 및 콜백 이름 생성
            if (obj is PTrigger trigger && source.Contains("{EventName}"))
            {
                var eventBuilder = new StringBuilder();

                string eventName = this.MappingProvider.GetEventName(trigger);

                source = source.Replace("{EventName}", eventName);

                foreach (var item in trigger
                         .GetExpressions()
                         .Where(e => e.Direction == BindDirection.Input && e.Input.BindOption == BindOptions.Input))
                {
                    var targetHost = item.Output.Host as PLayoutBinderHost;

                    var hostResult = buildImpl(trace, targetHost, source);

                    eventBuilder.AppendLine(hostResult.Source);

                    foreach (DXToken errorToken in hostResult.Errors)
                    {
                        result.AddErrorToken(errorToken);
                    }

                    foreach (DXToken resolvedToken in hostResult.Resolved)
                    {
                        result.AddErrorToken(resolvedToken);
                    }
                }

                sourceBuilder = new StringBuilder(eventBuilder.ToString());
            }

            // 토큰 처리
            foreach (DXToken token in DXToken.Parse(sourceBuilder.ToString()))
            {
                if (!IsSupportToken(token))
                {
                    result.Errors.Add(token);
                    continue;
                }

                bool tokenResult = false;

                switch (token.Token)
                {
                case "Property":
                    tokenResult = this.BuildProperty(trace, result, token, obj, sourceBuilder);
                    break;

                case "Function":
                    tokenResult = this.BuildFunction(trace, result, token, obj, sourceBuilder);
                    break;

                case "Target":
                    tokenResult = this.BuildTarget(trace, result, token, obj, sourceBuilder);
                    break;

                case "Param":
                    tokenResult = this.BuildParam(trace, result, token, obj, sourceBuilder);
                    break;
                }

                if (tokenResult)
                {
                    result.AddResolvedToken(token);
                }
                else
                {
                    result.AddErrorToken(token);

                    if (token.IsSafe)
                    {
                        sourceBuilder.Replace(token.OriginalSource, "");
                    }
                }
            }

            result.Source = sourceBuilder.ToString();

            return(result);
        }
コード例 #3
0
        private bool BuildFunction(BuildStackTrace trace, DXMappingResult result, DXToken token, object obj, StringBuilder source)
        {
            Type objType = obj.GetType();

            if (!token.HasParameter)
            {
                return(false);
            }

            // 클래스가 아닌경우
            if (!obj.GetType().IsClass)
            {
                return(false);
            }

            if (token.HasReturn)
            {
                // * 함수 정보에서 가져옴

                if (obj is PFunction pFunc)
                {
                    if (pFunc.Items.Find(BindOptions.Parameter).Count() != pFunc.ParameterInfos.Length)
                    {
                        return(false);
                    }

                    if (pFunc.FunctionInfo.RuntimeMethodInfo.HasAttribute <TAttribute>())
                    {
                        var tAttr   = pFunc.FunctionInfo.RuntimeMethodInfo.GetAttribute <TAttribute>();
                        var tResult = buildImpl(trace, pFunc, tAttr.MappingCode);

                        source.Replace(
                            token.OriginalSource,
                            $"({tResult.Source})");
                    }
                    else
                    {
                        List <string> lines = this.BuildBinderHost(trace, pFunc);

                        source.Replace(
                            token.OriginalSource,
                            this.MappingProvider.GetFunctionLine(pFunc, lines.ToArray()));
                    }

                    foreach (DXToken iToken in DXToken.Parse(source.ToString()))
                    {
                        result.AddErrorToken(iToken);
                    }
                }
            }
            else
            {
                // * 함수 호출 및 반환값으로 치환

                // 토큰 파라미터로 메서드 가져옴
                MethodInfo mi = objType.GetMethod(token.Parameters.FirstOrDefault());

                int depth = token.SubParameters.GetInt("depth");

                // 지원하지 않는 메서드
                if (!IsSupportMethod(mi))
                {
                    return(false);
                }
                if (mi == null || obj == null)
                {
                }
                // 메서드 호출
                string code = (string)mi.Invoke(obj, new object[] { depth });

                source.Replace(
                    token.OriginalSource,
                    code);

                return(true);
            }

            return(false);
        }
コード例 #4
0
        private bool BuildProperty(BuildStackTrace trace, DXMappingResult result, DXToken token, object obj, StringBuilder source)
        {
            try
            {
                Type objType = obj.GetType();

                if (!token.HasParameter)
                {
                    return(false);
                }

                // 클래스가 아닌경우
                if (!obj.GetType().IsClass)
                {
                    return(false);
                }

                // 인라인 파라미터
                bool inline = token.SubParameters.GetBool("inline");

                // 속성에서 실제값을 가져옴
                var propertySolve = SolvePropertyValue(obj, token.Parameters.FirstOrDefault());

                if (!propertySolve.Solved)
                {
                    return(false);
                }

                string valueLine = null;

                // 속성값이 바인더인 경우
                if (propertySolve.Result is PBinder binder)
                {
                    valueLine = this.BuildBinder(trace, result, binder);
                }
                else if (IsArrayType(propertySolve.Result?.GetType()))
                {
                    var sb   = new StringBuilder();
                    var list = propertySolve.Result as IList;

                    if (list.Count > 0)
                    {
                        foreach (object item in list)
                        {
                            if (sb.Length > 0)
                            {
                                sb.Append(", ");
                            }

                            if (item is PComponent)
                            {
                                var attr = item.GetAttribute <TAttribute>();

                                sb.Append(buildImpl(trace, item, attr.MappingCode).Source);
                            }
                            else
                            {
                                sb.Append(item);
                            }
                        }

                        valueLine = sb.ToString();
                    }
                }
                else if (propertySolve.Result is DependencyProperty prop)
                {
                    PropertyInfo targetPi = prop.OwnerType.GetProperty(prop.Name);

                    valueLine = this.MappingProvider.GetValueLine(targetPi, inline);
                }
                // 객체 참조인 경우
                else if (propertySolve.Result is Guid guid)
                {
                    foreach (var model in this.SharedConatiner.Values)
                    {
                        if (model is PObject pObj)
                        {
                            if (guid == pObj.Guid)
                            {
                                valueLine = this.MappingProvider.GetValueLine(this.SharedConatiner[pObj], inline);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    valueLine = this.MappingProvider.GetValueLine(propertySolve.Result, inline);
                }

                if (propertySolve.Result == null &&
                    obj is PTargetable targetable &&
                    targetable.TargetType == typeof(PBucket))
                {
                    // A.B = C;
                    // A.B(~~, C);
                    if (targetable.TargetBinder.Items.Count > 0 &&
                        targetable.TargetBinder.Items[0].Host is PDataBinding)
                    {
                        var bucket = targetable.TargetBinder.Items[0].Host as PDataBinding;

                        source.Replace(" = ", $"(\"{bucket.DataPath}\", ");
                        source.Replace(";", ");");

                        valueLine = "Update";
                    }
                }

                if (valueLine != null)
                {
                    // source 토큰 치환
                    foreach (DXToken innerToken in DXToken.Parse(valueLine))
                    {
                        source.Replace(innerToken.OriginalSource, "");
                    }

                    source.Replace(
                        token.OriginalSource,
                        valueLine);
                }
            }
            catch (Exception e)
            {
            }

            return(true);
        }