Exemple #1
0
        // 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));
            }
        }
Exemple #2
0
        // 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));
            }
        }