public override List <string> VisitStructuredBody([NotNull] LGFileParser.StructuredBodyContext context)
        {
            var templateRefValues = new Dictionary <string, List <string> >();
            var stb      = context.structuredTemplateBody();
            var result   = new JObject();
            var typeName = stb.structuredBodyNameLine().STRUCTURE_NAME().GetText();

            result[Evaluator.LGType] = typeName;
            var expandedResult = new List <JObject>
            {
                result
            };
            var bodys = stb.structuredBodyContentLine();

            foreach (var body in bodys)
            {
                var isKVPairBody = body.keyValueStructureLine() != null;
                if (isKVPairBody)
                {
                    var property = body.keyValueStructureLine().STRUCTURE_IDENTIFIER().GetText().ToLower();
                    var value    = VisitStructureValue(body.keyValueStructureLine());
                    if (value.Count > 1)
                    {
                        var valueList = new JArray();
                        foreach (var item in value)
                        {
                            var id = Guid.NewGuid().ToString();
                            valueList.Add(id);
                            templateRefValues.Add(id, item);
                        }

                        expandedResult.ForEach(x => x[property] = valueList);
                    }
                    else
                    {
                        var id = Guid.NewGuid().ToString();
                        expandedResult.ForEach(x => x[property] = id);
                        templateRefValues.Add(id, value[0]);
                    }
                }
                else
                {
                    var propertyObjects = EvalExpression(body.objectStructureLine().GetText()).Select(x => JObject.Parse(x)).ToList();
                    var tempResult      = new List <JObject>();
                    foreach (var res in expandedResult)
                    {
                        foreach (var propertyObject in propertyObjects)
                        {
                            var tempRes = JObject.FromObject(res);

                            // Full reference to another structured template is limited to the structured template with same type
                            if (propertyObject[Evaluator.LGType] != null && propertyObject[Evaluator.LGType].ToString() == typeName)
                            {
                                foreach (var item in propertyObject)
                                {
                                    if (tempRes.Property(item.Key) == null)
                                    {
                                        tempRes[item.Key] = item.Value;
                                    }
                                }
                            }

                            tempResult.Add(tempRes);
                        }
                    }

                    expandedResult = tempResult;
                }
            }

            var exps = expandedResult.Select(x => JsonConvert.SerializeObject(x)).ToList();

            var finalResult = new List <string>(exps);

            foreach (var templateRefValue in templateRefValues)
            {
                var tempRes = new List <string>();
                foreach (var res in finalResult)
                {
                    foreach (var refValue in templateRefValue.Value)
                    {
                        tempRes.Add(res.Replace(templateRefValue.Key, refValue));
                    }
                }

                finalResult = tempRes;
            }

            return(finalResult);
        }
Beispiel #2
0
        public override List <string> VisitStructuredBody([NotNull] LGFileParser.StructuredBodyContext context)
        {
            var idToStringDict = new Dictionary <string, string>();
            var stb            = context.structuredTemplateBody();
            var result         = new JObject();
            var typeName       = stb.structuredBodyNameLine().STRUCTURED_CONTENT().GetText().Trim();

            result["$type"] = typeName;
            var expandedResult = new List <JObject>();

            expandedResult.Add(result);
            var bodys = stb.structuredBodyContentLine().STRUCTURED_CONTENT();

            foreach (var body in bodys)
            {
                var line = body.GetText().Trim();

                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }

                var start = line.IndexOf('=');
                if (start > 0)
                {
                    // make it insensitive
                    var property    = line.Substring(0, start).Trim().ToLower();
                    var originValue = line.Substring(start + 1).Trim();

                    var valueArray = Evaluator.EscapeSeperatorRegex.Split(originValue);
                    if (valueArray.Length == 1)
                    {
                        var id = Guid.NewGuid().ToString();
                        expandedResult.ForEach(x => x[property] = id);
                        idToStringDict.Add(id, originValue);
                    }
                    else
                    {
                        var valueList = new JArray();
                        foreach (var item in valueArray)
                        {
                            var id = Guid.NewGuid().ToString();
                            valueList.Add(id);
                            idToStringDict.Add(id, item.Trim());
                        }

                        expandedResult.ForEach(x => x[property] = valueList);
                    }
                }
                else if (Evaluator.IsPureExpression(line))
                {
                    // [MyStruct
                    // Text = foo
                    // {ST2()}
                    // ]

                    // When the same property exists in both the calling template as well as callee, the content in caller will trump any content in the callee.
                    var propertyObjects = EvalExpression(line).Select(x => JObject.Parse(x)).ToList();
                    var tempResult      = new List <JObject>();
                    foreach (var res in expandedResult)
                    {
                        foreach (var propertyObject in propertyObjects)
                        {
                            var tempRes = JObject.FromObject(res);

                            // Full reference to another structured template is limited to the structured template with same type
                            if (propertyObject["$type"] != null && propertyObject["$type"].ToString() == typeName)
                            {
                                foreach (var item in propertyObject)
                                {
                                    if (tempRes.Property(item.Key) == null)
                                    {
                                        tempRes[item.Key] = item.Value;
                                    }
                                }
                            }

                            tempResult.Add(tempRes);
                        }
                    }

                    expandedResult = tempResult;
                }
            }

            var exps = expandedResult.Select(x => JsonConvert.SerializeObject(x)).ToList();
            var templateRefValues = new Dictionary <string, List <string> >();

            foreach (var idToString in idToStringDict)
            {
                // convert id text or expression to list of evaluated values
                if ((idToString.Value.StartsWith("@") || idToString.Value.EndsWith("{")) && idToString.Value.EndsWith("}"))
                {
                    templateRefValues.Add(idToString.Key, this.EvalExpression(idToString.Value));
                }
                else
                {
                    templateRefValues.Add(idToString.Key, this.EvalText(idToString.Value));
                }
            }

            var finalResult = new List <string>(exps);

            foreach (var templateRefValue in templateRefValues)
            {
                var tempRes = new List <string>();
                foreach (var res in finalResult)
                {
                    foreach (var refValue in templateRefValue.Value)
                    {
                        tempRes.Add(res.Replace(templateRefValue.Key, refValue));
                    }
                }

                finalResult = tempRes;
            }

            return(finalResult);
        }