public override List <Diagnostic> VisitStructuredTemplateBody([NotNull] LGFileParser.StructuredTemplateBodyContext context) { var result = new List <Diagnostic>(); var typeName = context.structuredBodyNameLine().STRUCTURED_CONTENT().GetText().Trim(); if (!structuredNameRegex.IsMatch(typeName)) { result.Add(BuildLGDiagnostic($"Structured type {typeName} is invalid. Letter, number, '_', '-' and '.' is allowed.", context: context.structuredBodyContentLine())); } var bodys = context.structuredBodyContentLine()?.STRUCTURED_CONTENT(); if (bodys == null || bodys.Length == 0 || bodys.All(u => string.IsNullOrEmpty(u.GetText()))) { result.Add(BuildLGDiagnostic($"Structured content is empty", context: context.structuredBodyContentLine())); } else { foreach (var body in bodys) { var line = body.GetText().Trim(); if (!string.IsNullOrWhiteSpace(line)) { var start = line.IndexOf('='); if (start < 0 && !Evaluator.IsPureExpression(line)) { result.Add(BuildLGDiagnostic($"Structured content does not support", context: context.structuredBodyContentLine())); } else { if (start > 0) { 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) { result.AddRange(CheckText(originValue, context.structuredBodyContentLine())); } else { foreach (var item in valueArray) { result.AddRange(CheckText(item.Trim(), context.structuredBodyContentLine())); } } } else if (Evaluator.IsPureExpression(line)) { result.AddRange(CheckExpression(line, context.structuredBodyContentLine())); } } } } } return(result); }
private List <string> EvalText(string exp) { if (string.IsNullOrEmpty(exp)) { return(new List <string>() { exp }); } if (Evaluator.IsPureExpression(exp)) { // @{} or {} text, get object result return(EvalExpression(exp)); } else { return(EvalTextContainsExpression(exp).Select(x => Regex.Unescape(x)).ToList()); } }
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); }