public static class_definition BuildClassDefinition(named_type_reference_list parents, params class_members[] cms) { var cb = new class_body_list(); foreach (var cm in cms) { cb.Add(cm); } var cd = new class_definition(parents, cb); return(cd); }
// frninja 23/04/16 - для шаблонных классов в yield public static class_definition BuildClassDefinition(named_type_reference_list parents, ident_list template_args, params class_members[] cms) { var cb = new class_body_list(); foreach (var cm in cms) { cb.Add(cm); } var cd = new class_definition(parents, cb, class_keyword.Class, template_args, null, class_attribute.None, false, null); return(cd); }
public static class_definition BuildClassOrRecordDefinition(bool is_class, params class_members[] cms) { var cb = new class_body_list(); foreach (var cm in cms) { cb.Add(cm); } var cd = new class_definition(cb); if (!is_class) { cd.keyword = class_keyword.Record; } return(cd); }
// end frninja // names и types передаю во внешний мир на предмет анализа того, что они не указатели. Снаружи они инициализируются пустыми списками public static void AddMembersForAutoClass(class_definition cd, ref List <ident> names, ref List <type_definition> types) // SSM 24.03.14 { //var types = new List<type_definition>(); class_body_list cb = cd.body; bool HasToString = false; bool HasConstructor = false; bool HasDeconstruct = false; foreach (var l in cb.class_def_blocks) { foreach (var m in l.members) { var mm = m as var_def_statement; if (mm != null) { if (mm.var_attr != definition_attribute.Static) { foreach (var v in mm.vars.idents) { names.Add(v); if (mm.vars_type != null) { types.Add(mm.vars_type); // во внешний мир для определения pointerов } else { types.Add(BuildSameType(mm.inital_value)); // почему-то только так хочет работать с рекурсивным типом Node<T> } } } } else { var ts = m as procedure_definition; if (!HasConstructor) { if (ts != null && ts.proc_header is constructor) { HasConstructor = true; } } if (!HasDeconstruct) { if (ts != null && ts.proc_header.name != null && ts.proc_header.name.meth_name.name != null) { HasDeconstruct = ts.proc_header.name.meth_name.name.ToLower().Equals("deconstruct"); } } if (!HasToString) { if (ts != null && ts.proc_header.name != null && ts.proc_header.name.meth_name.name != null) { HasToString = ts.proc_header.name.meth_name.name.ToUpper().Equals("TOSTRING"); } } } } } if (!HasConstructor) { var fnames = names.Select(x => new ident("f" + x.name)).ToList(); var cm = BuildSimpleConstructorSection(names, fnames, types); cb.Insert(0, cm); //cb.class_def_blocks.Insert(0, cm); } if (!HasDeconstruct) { var fnames = names.Select(x => new ident("f" + x.name)).ToList(); var cm = BuildSimpleDeconstructSection(names, fnames, types); cb.Add(cm); } if (!HasToString) { var tostr = BuildToStringFuncForAutoClass(names); cb.Add(BuildOneMemberSection(tostr)); //cb.class_def_blocks.Insert(0, BuildOneMemberSection(tostr)); } }
// end frninja // names и types передаю во внешний мир на предмет анализа того, что они не указатели. Снаружи они инициализируются пустыми списками public static void AddMembersForAutoClass(class_definition cd, ref List <ident> names, ref List <type_definition> types) // SSM 24.03.14 { //var types = new List<type_definition>(); class_body_list cb = cd.body; bool HasToString = false; bool HasConstructor = false; bool HasDeconstruct = false; foreach (var l in cb.class_def_blocks) { foreach (var m in l.members) { var mm = m as var_def_statement; if (mm != null) { if (mm.var_attr != definition_attribute.Static) { foreach (var v in mm.vars.idents) { names.Add(v); if (mm.vars_type != null) { types.Add(mm.vars_type); // во внешний мир для определения pointerов } else { types.Add(BuildSameType(mm.inital_value)); // почему-то только так хочет работать с рекурсивным типом Node<T> } } } } else { var ts = m as procedure_definition; if (!HasConstructor) { if (ts != null && ts.proc_header is constructor && (ts.proc_header.parameters?.params_list.SelectMany(tp => tp.idents.idents).Count() ?? 0) == names.Count ) { HasConstructor = true; // на самом деле это означает, что есть конструктор с точно таким же количеством параметров } } if (!HasDeconstruct) { if (ts != null && ts.proc_header.name != null && ts.proc_header.name.meth_name.name != null) { HasDeconstruct = ts.proc_header.name.meth_name.name.ToLower().Equals("deconstruct"); } } if (!HasToString) { if (ts != null && ts.proc_header.name != null && ts.proc_header.name.meth_name.name != null) { HasToString = ts.proc_header.name.meth_name.name.ToUpper().Equals("TOSTRING"); } } } } } // добавление свойств - временно убрал т.к. свойства нельзя передавать как var-параметры // По идее если это делать, то поля переименовывать везде в классе!!! /*for (var i=0; i<names.Count; i++) * { * if (names[i].name.StartsWith("#")) * continue; * var propName = names[i].TypedClone(); * names[i].name = "!" + names[i].name; * var simpleProp = BuildSimpleReadWriteProperty(propName, names[i].name, types[i]); * var cm = BuildOneMemberSection(simpleProp); * cb.Add(cm); * }*/ if (!HasConstructor) { var fnames = names.Select(x => new ident("f" + x.name.ToLower(), x.source_context)).ToList(); if (fnames.Select(x => x.name).Distinct().Count() != names.Count) // SSM 20/05/2020 #2126 { return; // хак - мы не генерируем конструктор, потому что ошибка одинаковых имен выведется позже } var cm = BuildSimpleConstructorSection(names, fnames, types); cb.Insert(0, cm); //cb.class_def_blocks.Insert(0, cm); } if (!HasDeconstruct) { var fnames = names.Select(x => new ident("f" + x.name, x.source_context)).ToList(); var cm = BuildSimpleDeconstructSection(names, fnames, types); cb.Add(cm); } if (!HasToString) { var tostr = BuildToStringFuncForAutoClass(names); var cm = BuildOneMemberSection(tostr); cb.Add(cm); //cb.class_def_blocks.Insert(0, BuildOneMemberSection(tostr)); } }