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); }
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); }
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); }
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); }