internal static void ProcessBinderValue(DXMapper <JSCodeMapAttribute> mapper, IndentStringBuilder sourceBuilder, DXToken token, PBinder binder) { string valueLine = null; // 직접 입력 if (binder.IsDirectValue) { object value = binder.DirectValue; if (value is string vStr) { Match match = Regex.Match("(?<=^\")(\\d+\\.\\d+|\\d+)(?= \"$)", vStr); if (match.Success) { valueLine = vStr; } else if (double.TryParse(vStr, out double r)) { valueLine = r.ToString(); } } if (valueLine == null) { valueLine = mapper.MappingProvider.GetValueLine(value, true); } } // 연결됨 else if (binder.Items.Count == 1) { var paramOutputHost = binder.Items[0].Host; var attr = paramOutputHost.GetAttribute <JSCodeMapAttribute>(); if (paramOutputHost is PTrigger) { valueLine = "sender"; } else { valueLine = 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); } }
// CreateScope (Recursive) internal static string CreateScope(DXMapper <CSharpCodeMapAttribute> mapper, CodeComponent <CSharpCodeMapAttribute>[] scopeComponents, NameContainer localVariableContainer, bool isCodeBlock = false) { var scopeBuilder = new IndentStringBuilder(); var stack = new Stack <CodeComponent <CSharpCodeMapAttribute> >(scopeComponents.Reverse()); if (!isCodeBlock) { scopeBuilder.AppendLine(); scopeBuilder.AppendLine("{"); } while (stack.Count > 0) { var cc = stack.Pop(); var mappingResult = 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.Parameters[0]) - 1; if (host is PFunction) { index++; } var scopeBinder = host[BindOptions.Output].ElementAt(index) as PBinder; var scopeZeroHosts = scopeBinder.Items.Select(b => b.GetBinderHost()); var childScopeComponents = BinderHelper.FindZeroLevelNodes(scopeZeroHosts, withRoot: true) .Distinct() .Select(childHost => new CodeComponent <CSharpCodeMapAttribute>( childHost, childHost.GetAttribute <CSharpCodeMapAttribute>())) .ToArray(); sourceBuilder.Replace( token.OriginalSource, CreateScope(mapper, childScopeComponents, localVariableContainer)); break; } case "Line": { if (!token.IsIndexed) { continue; } int index = int.Parse(token.Parameters[0]) - 1; var paramBinder = host[BindOptions.Parameter].ElementAt(index) as PBinder; ProcessBinderValue(mapper, sourceBuilder, token, paramBinder); break; } default: break; } } } scopeBuilder.AppendBlock(sourceBuilder.ToString(), 1); scopeBuilder.AppendLine(); } if (!isCodeBlock) { scopeBuilder.AppendLine("}"); } return(scopeBuilder.ToString()); }
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); } } }