static Dictionary <TAttr, object> ParseAttrs <TAttr>(Generator.Ctx ctx, IEnumerable <string> comments, params TAttr[] firstLineDefaultKeys ) where TAttr : struct { bool firstLine = true; var lstDescr = new List <string>(); Dictionary <TAttr, object> attrs = null; int iDefaultKey = (firstLineDefaultKeys.Length > 0) ? 0 : -1; foreach (var txt in comments) { bool isKeyValueComment; { int iEqualSign = txt.IndexOf('='); if (iEqualSign > 0) { isKeyValueComment = !Enumerable.Range(0, iEqualSign - 1).Any(i => char.IsWhiteSpace(txt[i])); } else { isKeyValueComment = false; } } if ((firstLineDefaultKeys.Length == 0 || !firstLine) && !isKeyValueComment) { if (txt.Trim().Length == 0) { lstDescr.Clear(); } else { lstDescr.Add(txt); } continue; // do not parse simple comment lines } foreach (Expr attr in Parser.ParseSequence(txt, comparison: StringComparison.InvariantCulture)) { string attrName; Expr attrValue; if (attr.nodeType == ExprType.Equal) { // named attribute var be = (BinaryExpr)attr; if (be.left.nodeType == ExprType.Reference) { attrName = Convert.ToString(be.left); } else { var name = Generator.Generate(be.left, ctx); if (OPs.KindOf(name) != ValueKind.Const) { ctx.Error("ParseAttrs: attribute name must be constant\t" + be.left.ToString()); } attrName = Convert.ToString(name); } attrValue = be.right; } else if (firstLine && iDefaultKey >= 0) { // unnamed attributes possible in first line attrs = attrs ?? new Dictionary <TAttr, object>(); attrs.Add(firstLineDefaultKeys[iDefaultKey], attr); if (++iDefaultKey >= firstLineDefaultKeys.Length) { iDefaultKey = -1; } continue; } else { break; // it is simple comment to the end of line? } if (attrValue.nodeType != ExprType.Constant) { attrValue = new CallExpr(FuncDefs_Core._block, attrValue); } var value = Generator.Generate(attrValue, ctx); if (OPs.KindOf(value) != ValueKind.Const) { ctx.Error(string.Format("ParseAttrs: attribute value must be constant\t{0}={1}", attrName, attrValue)); } if (attrName != null) { if (!Enum.TryParse <TAttr>(attrName, out var attrKey)) { throw new Generator.Exception($"Unrecognized attribute name, {attrName}={attrValue} // enum {typeof(TAttr)}"); } attrs = attrs ?? new Dictionary <TAttr, object>(); Attr.Add(attrs, attrKey, value, false); } } firstLine = false; } if (lstDescr.Count > 0) { attrs = attrs ?? new Dictionary <TAttr, object>(); if (!Enum.TryParse <TAttr>(nameof(Attr.Tbl.Description), out var attrDescription)) { throw new Generator.Exception($"ParseAttrs: enum '{typeof(TAttr)}' does not contains value named '{nameof(Attr.Tbl.Description)}'"); } attrs.Add(attrDescription, lstDescr); } return(attrs); }
internal static SqlFuncPreprocessingCtx NewCodeLookupDict(SqlFuncPreprocessingCtx src, SqlInfo tmpl, string descriptor, Dictionary <Attr.Col, object> descrFieldAttrs) { var select = tmpl.sql[SqlSectionExpr.Kind.Select]; var innerAttrs = new List <Dictionary <Attr.Col, object> >(select.args.Count + 1); var sb = new StringBuilder(); foreach (var kind in SqlSectionExpr.EnumKinds()) { var section = tmpl.sql[kind]; switch (kind) { case SqlSectionExpr.Kind.Select: { sb.AppendLine("SELECT"); var modFunc = src.ldr.ModifyFieldExpr(src, descriptor); var unmFunc = src.ldr.ModifyFieldExpr(src, null); var tmplInnerAttrs = (Dictionary <Attr.Col, object>[])tmpl.attrs[Attr.Tbl._columns_attrs]; for (int i = 0; i < select.args.Count; i++) { var attrs = tmplInnerAttrs[i]; if (i > 0) { sb.AppendLine(","); } object v; if (Attr.GetBool(attrs, Attr.Col.FixedAlias)) { v = unmFunc(select.args[i], attrs); } else { v = modFunc(select.args[i], attrs); } sb.Append($"\t{v}"); innerAttrs.Add(attrs); } sb.AppendLine(); } break; case SqlSectionExpr.Kind.From: if (section != null) { sb.AppendLine(section.ToString()); } else { sb.AppendLine($"FROM {descriptor}"); } break; default: if (section != null) { sb.AppendLine(section.ToString()); } break; } } var tblAttrs = new Dictionary <Attr.Tbl, object>(tmpl.attrs); var c = new SqlFuncPreprocessingCtx() { ldr = src.ldr, actualityInDays = Attr.defaultActualityDays * 10, arrayResults = true, funcNamesPrefix = descriptor + "_DictData", tblAttrs = tblAttrs, queryText = sb.ToString(), }; tblAttrs.Remove(Attr.Tbl.LookupTableTemplate); string tmplDescr; { string srcTableComment = Attr.OneLineText(src.tblAttrs.Get(Attr.Tbl.Description)); string tmplDescrComment = Attr.OneLineText(descrFieldAttrs.Get(Attr.Col.Description)); if (tblAttrs.TryGetValue(Attr.Tbl.TemplateDescription, out var objTmplDescr)) { tmplDescr = string.Format(Convert.ToString(objTmplDescr), descriptor, tmplDescrComment, srcTableComment); } else { tmplDescr = $"Instantiated lookup table for\t{descriptor}\t{tmplDescrComment}\t{srcTableComment}"; } } tblAttrs.Remove(Attr.Tbl.TemplateDescription); tblAttrs[Attr.Tbl.FuncPrefix] = c.funcNamesPrefix; Attr.Add(tblAttrs, Attr.Tbl.Description, tmplDescr, true); if (!src.isTimed) { tblAttrs.Remove(Attr.Tbl.ActualityDays); } else if (!tblAttrs.ContainsKey(Attr.Tbl.ActualityDays)) { tblAttrs.Add(Attr.Tbl.ActualityDays, c.actualityInDays); } tblAttrs[Attr.Tbl.ArrayResults] = true; tblAttrs[Attr.Tbl._columns_attrs] = innerAttrs; return(c); }