Esempio n. 1
0
        /// <summary>
        /// Поиск символа в пространстве имен.
        /// </summary>
        /// <param name="name">Имя для поиска.</param>
        /// <returns>Первый элемент списка найденных имен. null если ни чего не найдено.</returns>
        public override SymbolInfoList find(string name)
        {
            bool           is_ns = NetHelper.NetHelper.IsNetNamespace(_name + "." + name);
            SymbolInfoList sil   = null;

            if (is_ns)
            {
                compiled_namespace_node cnn = compiled_namespace_node.get_compiled_namespace(_name + "." + name, _tcst);
                sil = new SymbolInfoList(new SymbolInfo(cnn));
            }
            else
            {
                //Kolay changed next string.   throwOnError=false  ignoreCase=true,   .
                //Type t = Type.GetType(_name+"."+name,false,true);
                if (common_namespace != null)
                {
                    sil = common_namespace.scope.FindOnlyInScope(name);
                    if (sil != null)
                    {
                        return(sil);
                    }
                }
                Type t = NetHelper.NetHelper.FindType(_name + "." + name);
                if (t != null)
                {
                    sil = new SymbolInfoList(new SymbolInfo(compiled_type_node.get_type_node(t, _tcst)));
                }
                else
                {
                    t = NetHelper.NetHelper.FindType(_name + "." + _name);
                    if (t != null && NetHelper.NetHelper.IsEntryType(t))
                    {
                        sil = NetHelper.NetHelper.FindName(t, name);
                        if (sil == null)
                        {
                            type_node tn = NetHelper.NetHelper.FindCompiledPascalType(_name + "." + name);
                            if (tn != null)
                            {
                                sil = new SymbolInfoList(new SymbolInfo(tn));
                            }
                            else
                            {
                                template_class tc = NetHelper.NetHelper.FindCompiledTemplateType(_name + "." + name);
                                if (tc != null)
                                {
                                    sil = new SymbolInfoList(new SymbolInfo(tc));
                                }
                            }
                        }
                    }
                }
            }
            return(sil);
        }
 private void VisitTemplateClassDefinition(template_class tclass)
 {
     int offset = 0;
     offset = SavePositionAndConstPool(tclass);//SavePosition(tclass);
     bw.Write((byte)tclass.semantic_node_type);
     //Пишем название шаблонного класса
     bw.Write(tclass.name);
     if (tclass.is_synonym)
         bw.Write((byte)1);
     else
         bw.Write((byte)0);
     //bw.Write(GetUnitReference(tclass.cnn)); //(ssyy) Нужно ли это?
     //Пишем имена подключаемых сборок
     bw.Write(tclass.using_list.Count);
     foreach (using_namespace un in tclass.using_list)
     {
         bw.Write(un.namespace_name);
     }
     if (tclass.using_list2 == null)
     {
         bw.Write((byte)0);
     }
     else
     {
         bw.Write((byte)1);
         bw.Write(tclass.using_list2.Count);
         foreach (using_namespace un in tclass.using_list2)
         {
             bw.Write(un.namespace_name);
         }
     }
     //Пишем имя файла, где описан шаблон
     if (tclass.cur_document == null)
         bw.Write((byte)0);
     else
     {
         bw.Write((byte)1);
         bw.Write(Path.GetFileName(tclass.cur_document.file_name));
     }
     SyntaxTree.SyntaxTreeStreamWriter stw = new SyntaxTree.SyntaxTreeStreamWriter();
     stw.bw = bw;
     if (tclass.type_dec == null)
     {
         bw.Write((byte)0);
     }
     else
     {
         bw.Write((byte)1);
         //Пишем синтаксическое дерево шаблона
         tclass.type_dec.visit(stw);
     }
     bw.Write(tclass.external_methods.Count);
     foreach (procedure_definition_info pdi in tclass.external_methods)
     {
         if (pdi.nspace.scope is SymbolTable.UnitImplementationScope)
         {
             bw.Write((byte)1);
         }
         else
         {
             bw.Write((byte)0);
         }
         if (pdi.proc == null)
         {
             bw.Write((byte)0);
         }
         else
         {
             bw.Write((byte)1);
             pdi.proc.visit(stw);
         }
     }
 }
 private void WriteTemplateClassReference(template_class tc)
 {
     byte is_def = 0;
     int t_offset = GetTemplateTypeReference(tc, ref is_def);
     bw.Write(is_def); //пишем флаг импортируемый ли это тип или нет
     bw.Write(t_offset); // сохраняем его смещение (это либо смещение в самом модуле, либо в списке импорт. сущностей)
 }
 //ssyy
 private int GetTemplateTypeReference(template_class tc, ref byte is_def)
 {
     int off = 0;
     if (members.TryGetValue(tc, out off)) //если этот тип описан в этом модуле
     {
         is_def = 1;
         return off;//возвращаем его смещение
     }
     //иначе он описан в другом модуле
     is_def = 0;
     ImportedEntity ie = null;
     if (ext_members.TryGetValue(tc, out ie))
     {
         return ie.index * ie.GetSize();
     }
     ie = new ImportedEntity();
     ie.flag = ImportKind.Common;
     ie.num_unit = GetUnitToken(tc.cnn);//получаем модуль
     ie.offset = GetExternalOffset(tc);//получаем смещение в другом модуле
     int offset = imp_entitles.Count * ie.GetSize();
     ie.index = imp_entitles.Count;
     imp_entitles.Add(ie);
     ext_members[tc] = ie;
     return offset;
 }
        public common_type_node instance(template_class tc, List<type_node> template_params, location loc)
        {
            //Проверяем, что попытка инстанцирования корректна
            SyntaxTree.class_definition cl_def = tc.type_dec.type_def as SyntaxTree.class_definition;
            SyntaxTree.template_type_name ttn = tc.type_dec.type_name as SyntaxTree.template_type_name;
#if (DEBUG)
            if (!tc.is_synonym)
            {
                if (cl_def == null)
                {
                    throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No body definition in template class.");
                }
                if (cl_def.template_args == null || cl_def.template_args.idents == null)
                {
                    throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No template arguments in syntax tree.");
                }
            }
            else
            {
                if (ttn == null)
                {
                    throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No template name.");
                }
            }
#endif
            List<SyntaxTree.ident> template_formals = (tc.is_synonym) ?
                ttn.template_args.idents : cl_def.template_args.idents;
            if (template_formals.Count != ttn.template_args.idents.Count)
            {
                AddError(loc, "TEMPLATE_ARGUMENTS_COUNT_MISMATCH");
            }

            if (!tc.is_synonym)
            {
                foreach (type_node tnode in template_params)
                {
                    if (depended_from_generic_parameter(tnode))
                    {
                        AddError(loc, "TEMPLATES_AND_GENERICS_ARE_INCOMPATIBLE");
                    }
                }
            }

            //А вдруг такая инстанция уже есть - вернём её
            string inst_name = tc.CreateTemplateInstance(template_params, loc);
            SymbolInfo si = tc.cnn.scope.FindOnlyInScope(inst_name);
            if (si != null)
            {
                return (common_type_node)si.sym_info;
            }

            //Переходим в место описания шаблона
            common_namespace_node current_namespace = context.converted_namespace;
            context.converted_namespace = tc.cnn;
            common_type_node current_type = context.converted_type;
            context.converted_type = null;
            template_class current_template = context.converted_template_type;
            context.converted_template_type = null;
            compiled_type_node current_compiled_type = context.converted_compiled_type;
            context.converted_compiled_type = null;
            common_function_node_stack current_funk_stack = context.converted_func_stack;
            context.converted_func_stack = new common_function_node_stack(); //Думаю, это будет работать

            //DarkStar
            statement_list_stack statement_list_stack = convertion_data_and_alghoritms.statement_list_stack;
            convertion_data_and_alghoritms.statement_list_stack = new statement_list_stack();

            bool current_cur_meth_not_in_class = current_converted_method_not_in_class_defined;
            current_converted_method_not_in_class_defined = false;
            SymbolInfo current_last_created_function = context.last_created_function;
            context.last_created_function = null;
            bool current_record_created = _record_created;
            _record_created = false;
            SemanticTree.field_access_level current_fal = context.get_field_access_level();
            document current_doc = current_document;
            current_document = tc.cur_document;
            bool current_body_exists = body_exists;
            body_exists = false;
            bool current_allow_inherited_ctor_call = context.allow_inherited_ctor_call;
            bool current_is_direct_type_decl = is_direct_type_decl;
            is_direct_type_decl = false;
            context.allow_inherited_ctor_call = false;
            bool current_type_section_converting = type_section_converting;
            type_section_converting = true;
            SemanticTree.field_access_level curr_fal = context.get_field_access_level();
            List<var_definition_node> current_var_defs = context.var_defs;
            context.var_defs = new List<var_definition_node>();
            Hashtable current_member_decls = context.member_decls;
            context.member_decls = new Hashtable();
            //подменяем using-список 
            using_namespace_list current_using_list = new using_namespace_list();
            foreach (using_namespace un in using_list)
            {
                current_using_list.AddElement(un);
            }
            using_list.clear();
            foreach (using_namespace un in tc.using_list)
            {
                using_list.AddElement(un);
            }
            context.converted_type = null; 
            context.enter_code_block_without_bind();

            common_type_node ctn;

            bool interface_creating = false;

            //Создаём инстанцию шаблона
            if (tc.is_synonym)
            {
                ctn = context.create_type(inst_name, get_location(ttn));
            }
            else
            {
                if (cl_def.keyword == SyntaxTree.class_keyword.Record)
                {
                    ctn = context.create_record_type(get_location(tc.type_dec.type_name), inst_name);
                }
                else
                {
                    interface_creating = (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface);
                    ctn = context.advanced_create_type(inst_name, get_location(tc.type_dec.type_name), interface_creating);
                }
            }
            ctn.original_template = tc;
            bool indefinite = false;
            foreach (type_node tn in template_params)
            {
                indefinite = indefinite || tn.depended_from_indefinite;
            }
            ctn.SetDependedFromIndefinite(indefinite);
            tc.instance_params.Add(ctn, template_params);

            //Ставим в соответствие формальным параметрам шаблона фактические
            for (int i = 0; i < template_params.Count; i++)
            {
                ctn.Scope.AddSymbol(template_formals[i].name, new SymbolInfo(template_params[i]));
            }

            //Разбор тела класса
            if (tc.is_synonym)
            {
                type_node synonym_value = convert_strong(tc.type_dec.type_def);
                ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name,
                    synonym_value, ctn, PascalABCCompiler.SemanticTree.polymorphic_state.ps_static,
                    PascalABCCompiler.SemanticTree.field_access_level.fal_public, null));
            }
            else
            {
                if (cl_def.keyword == SyntaxTree.class_keyword.Record)
                {
                    _record_created = true;
                }

                bool tmp_direct = is_direct_type_decl;
                is_direct_type_decl = true;
                hard_node_test_and_visit(cl_def);
                is_direct_type_decl = tmp_direct;

                //Разбор методов, описанных вне класса
                if (!interface_creating)
                {
                    type_section_converting = false;
                    foreach (procedure_definition_info pdi in tc.external_methods)
                    {
                        if (context.converted_namespace != pdi.nspace)
                        {
                            context.converted_namespace = pdi.nspace;
                            using_namespace_list ulist =
                                (pdi.nspace == tc.cnn) ? tc.using_list : tc.using_list2;
                            using_list.clear();
                            foreach (using_namespace un in ulist)
                            {
                                using_list.AddElement(un);
                            }
                            template_class.AddUsingListToScope(context.converted_namespace.scope, ulist);
                        }

                        //Заменяем в дереве метода имя шаблонного класса на имя инстанции
                        string tmp_name = pdi.proc.proc_header.name.class_name.name;
                        pdi.proc.proc_header.name.class_name.name = inst_name;

                        hard_node_test_and_visit(pdi.proc);

                        //Обратная замена
                        pdi.proc.proc_header.name.class_name.name = tmp_name;
                    }

                    foreach (common_method_node cmn in ctn.methods)
                    {
                        if (cmn.function_code == null)
                        {
                            AddError(cmn.loc, "FUNCTION_PREDEFINITION_WITHOUT_DEFINITION");
                        }
                    }
                }
            }

            //Прыжок обратно
            context.leave_code_block();
            context.converted_namespace = current_namespace;
            context.converted_type = current_type;
            context.converted_template_type = current_template;
            context.set_field_access_level(current_fal);
            context.converted_func_stack = current_funk_stack;
            context.converted_compiled_type = current_compiled_type;
            convertion_data_and_alghoritms.statement_list_stack = statement_list_stack;
            current_document = current_doc;
            body_exists = current_body_exists;
            _record_created = current_record_created;
            context.last_created_function = current_last_created_function;
            is_direct_type_decl = current_is_direct_type_decl;
            context.allow_inherited_ctor_call = current_allow_inherited_ctor_call;
            current_converted_method_not_in_class_defined = current_cur_meth_not_in_class;
            context.set_field_access_level(curr_fal);
            type_section_converting = current_type_section_converting;
            context.member_decls = current_member_decls;
            context.var_defs = current_var_defs;
            using_list.clear();
            foreach (using_namespace un in current_using_list)
            {
                using_list.AddElement(un);
            }

            return ctn;
        }
 public type_node instance_any(template_class tc, List<type_node> template_params, location loc)
 {
     common_type_node t = instance(tc, template_params, loc);
     if (tc.is_synonym)
     {
         return t.fields[0].type;
     }
     return t;
 }
        public override void visit(SyntaxTree.type_declaration _type_declaration)
        {
            //bool is_template_synonym = false;
            //SyntaxTree.array_type at=_type_declaration.type_def as SyntaxTree.array_type;
            template_class tc = null;
            SyntaxTree.template_type_name ttn = _type_declaration.type_name as SyntaxTree.template_type_name;
            SyntaxTree.class_definition cl_def = _type_declaration.type_def as SyntaxTree.class_definition;
            SyntaxTree.function_header function_header = _type_declaration.type_def as SyntaxTree.function_header;
            SyntaxTree.procedure_header procedure_header = _type_declaration.type_def as SyntaxTree.procedure_header;
            if (cl_def != null && (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial && cl_def.keyword != SyntaxTree.class_keyword.Class)
            {
                AddError(get_location(_type_declaration), "ONLY_CLASS_CAN_BE_PARTIAL");
            }
            if (ttn != null && cl_def == null && function_header == null && procedure_header == null)
            {
                location t_loc = get_location(ttn);
                context.check_name_free(ttn.name, t_loc);
                tc = new template_class(_type_declaration, ttn.name,
                    context.converted_namespace,
                    current_document, using_list);
                tc.is_synonym = true;
                //Проверяем параметры шаблона на совпадение друг с другом
                check_param_redeclared(ttn.template_args.idents);
                context.AddTemplate(ttn.name, tc, t_loc);
                return;

                //is_template_synonym = true;
                //AddError(new TemplateCanBeClassOnly(get_location(ttn)));
            }
            if ((function_header != null) || (procedure_header != null))
            {
                location loc;
                if (function_header != null)
                    loc = get_location(function_header);
                else
                    loc = get_location(procedure_header);
                string del_name = _type_declaration.type_name.name;
                if (ttn != null)
                {
                    if (context.top_function != null)
                    {
                        AddError(loc, "GENERIC_DELEGATE_INNER_FUNCTION");
                    }
                    del_name += compiler_string_consts.generic_params_infix + ttn.template_args.idents.Count;
                }
                context.check_name_free(del_name, loc);
                common_type_node del_type = convertion_data_and_alghoritms.type_constructor.create_delegate_without_init(
                    del_name, context.converted_namespace, loc);
                //(ssyy) Обработка дженериков
                common_type_node tmp_converted_type = null;
                if (ttn != null)
                {
                    tmp_converted_type = context.converted_type;
                    context.converted_type = del_type;
                    visit_generic_params(del_type, ttn.template_args.idents);
                }
                if (function_header != null)
                {
                    del_type = convert_function_type(function_header, loc, del_name, del_type);
                }
                else
                {
                    del_type = convert_function_type(procedure_header, loc, del_name, del_type);
                }
                if (ttn != null)
                {
                    context.converted_type = tmp_converted_type;
                }
                //blocks.converted_namespace.types.AddElement(del_type);
                CheckWaitedRefTypes(del_type);
                if (_type_declaration.attributes != null)
            	{
                	make_attributes_for_declaration(_type_declaration,del_type);
                }
                context.converted_namespace.scope.AddSymbol(del_name, new SymbolInfo(del_type));
                return;
            }
            if (cl_def == null && ttn == null)
            {
                string name = _type_declaration.type_name.name;
                location loc = get_location(_type_declaration.type_name);
                context.check_name_free(name, loc);
                is_direct_type_decl = true;
                type_node tn = convert_strong(_type_declaration.type_def);
                assign_doc_info(tn,_type_declaration);
                is_direct_type_decl = false;
                if (_type_declaration.type_def is SyntaxTree.named_type_reference||
                    _type_declaration.type_def is SyntaxTree.ref_type || _type_declaration.type_def is SyntaxTree.string_num_definition ||
                    tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_kind)// ||
                    /*tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type*/
                {
                	if (context.converted_func_stack.Empty)
                	{
                		type_synonym ts = new type_synonym(name, tn, loc);
                		assign_doc_info(ts,_type_declaration);
                		context.converted_namespace.type_synonyms.Add(ts);
                	}
                }
                else
                {
                    tn.SetName(context.BuildName(name));
                }
                if (_type_declaration.attributes != null)
                if (_type_declaration.type_def is SyntaxTree.enum_type_definition)
                {
                	make_attributes_for_declaration(_type_declaration,tn);
                	(tn as common_type_node).add_additional_enum_operations();
                }
                else
                    AddError(get_location(_type_declaration.attributes), "ATTRIBUTES_APPLICABLE_ONLY_TO_THESE_TYPES");
                context.add_type(name, tn, loc);
                return;
            }
            //Проверим, что список template-ов не пуст
            bool is_generic = false;
            if (ttn != null && cl_def != null && cl_def.template_args == null)
            {
                cl_def.template_args = ttn.template_args;
            }
            if (cl_def != null && cl_def.template_args != null && cl_def.template_args.idents != null &&
                cl_def.template_args.idents.Count > 0)
            {
                switch (cl_def.keyword)
                {
                    case PascalABCCompiler.SyntaxTree.class_keyword.TemplateClass:
                        cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Class;
                        is_generic = false;
                        check_where_section(cl_def);
                        break;
                    case PascalABCCompiler.SyntaxTree.class_keyword.TemplateRecord:
                        cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Record;
                        is_generic = false;
                        check_where_section(cl_def);
                        break;
                    case PascalABCCompiler.SyntaxTree.class_keyword.TemplateInterface:
                        cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Interface;
                        is_generic = false;
                        check_where_section(cl_def);
                        break;
                    default:
                        is_generic = true;
                        break;
                }

                //if (is_generic)
                //{
                //    throw new NotSupportedError(get_location(_type_declaration.type_name));
                //}
                if (!is_generic)
                {
                    string t_name = _type_declaration.type_name.name;
                    location t_loc = get_location(_type_declaration.type_name);
                    SymbolInfo si = context.find_only_in_namespace(t_name);

                    tc = null;
                    //Ищем предописание
                    if (si != null)
                    {
                        tc = si.sym_info as template_class;
                        if (tc == null || !tc.ForwardDeclarationOnly)
                        {
                            AddError(new NameRedefinition(t_name, convertion_data_and_alghoritms.get_location(si.sym_info), t_loc));
                        }
                        SyntaxTree.class_definition prev_cl_def = tc.type_dec.type_def as SyntaxTree.class_definition;
                        if (prev_cl_def.keyword != cl_def.keyword || prev_cl_def.template_args.idents.Count != cl_def.template_args.idents.Count)
                        {
                            AddError(t_loc, "FORWARD_TEMPLATE_{0}_DECLARATION_MISMATCH_DECLARATION", t_name);
                        }
                        for (int k = 0; k < cl_def.template_args.idents.Count; k++)
                        {
                            if (string.Compare(cl_def.template_args.idents[k].name, prev_cl_def.template_args.idents[k].name, true) != 0)
                            {
                                AddError(t_loc, "FORWARD_TEMPLATE_{0}_DECLARATION_MISMATCH_DECLARATION", t_name);
                            }
                        }
                        if (cl_def.body == null)
                        {
                            AddError(new NameRedefinition(t_name, convertion_data_and_alghoritms.get_location(si.sym_info), t_loc));
                        }
                        tc.type_dec = _type_declaration;
                        tc.ForwardDeclarationOnly = false;
                        return;
                    }

                    tc = new template_class(_type_declaration, t_name,
                        context.converted_namespace, 
                        current_document, using_list);

                    //Проверяем параметры шаблона на совпадение друг с другом
                    check_param_redeclared(cl_def.template_args.idents);

                    tc.ForwardDeclarationOnly = cl_def.body == null;
                    context.AddTemplate(t_name, tc, t_loc);
                    if (!tc.ForwardDeclarationOnly && template_class.check_template_definitions)
                    {
                        int count = cl_def.template_args.idents.Count;
                        List<type_node> test_types = new List<type_node>(count);
                        for (int i = 0; i < count; i++)
                        {
                            test_types.Add(new indefinite_type_node(cl_def.template_args.idents[i].name));
                        } 
                        instance(tc, test_types, t_loc);
                    }
                    return;
                }
            }
            //(ssyy) Теперь проверим на модификатор template
            if (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateClass ||
                cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateRecord ||
                cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateInterface)
            {
                //Ошибка, т.к. нет списка шаблонных параметров.
                AddError(get_location(_type_declaration.type_name), "TEMPLATE_PARAMS_EXPECTED");
            }
            if (is_generic)
            {
                context.check_name_free(_type_declaration.type_name.name, get_location(_type_declaration.type_name));
                _type_declaration.type_name.name += compiler_string_consts.generic_params_infix +
                    cl_def.template_args.idents.Count.ToString();
            }
            if (cl_def.keyword == SyntaxTree.class_keyword.Record)
            {
                string name = record_type_name = _type_declaration.type_name.name;
                record_is_generic = is_generic;
                location loc = get_location(_type_declaration.type_name);
                context.check_name_free(name, loc);
                //context.create_record_type(loc, record_type_name);
                is_direct_type_decl = true;
                type_node tn = convert_strong(_type_declaration.type_def);
                assign_doc_info(tn,_type_declaration);
                if (_type_declaration.attributes != null)
            	{
            		make_attributes_for_declaration(_type_declaration, tn);
            	}
                is_direct_type_decl = false;
                record_type_name = null;
                record_is_generic = false;
                tn.SetName(context.BuildName(name));
                return;
            }

            //(ssyy) Флаг показывает, создаём ли мы интерфейс
            bool interface_creating = (/*cl_def != null &&*/ cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface);

            common_type_node ctn = context.advanced_create_type(_type_declaration.type_name.name, get_location(_type_declaration.type_name), interface_creating, (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial);
            assign_doc_info(ctn,_type_declaration);
            if (is_generic)
            {
                context.create_generic_indicator(ctn);
                visit_generic_params(ctn, cl_def.template_args.idents);
            }
            visit_where_list(cl_def.where_section);
            CheckWaitedRefTypes(ctn);
            is_direct_type_decl = true;
            hard_node_test_and_visit(_type_declaration.type_def);

            // frninja 28/04/16 - режем мусорные методы хелперы yield
            {
                var toRemove = ctn.methods.Where(m => m.name.StartsWith(YieldHelpers.YieldConsts.YieldHelperMethodPrefix)).ToArray();
                foreach (var m in toRemove)
                {
                    ctn.methods.remove(m);
                }
            }
            // end frninja

            is_direct_type_decl = false;
            if (_type_declaration.attributes != null)
            {
            	make_attributes_for_declaration(_type_declaration, ctn);
            }
        }
Esempio n. 8
0
 public void AddTemplate(string name, template_class tc, location loc)
 {
     check_name_free(name, loc);
     _cmn.scope.AddSymbol(name, new SymbolInfo(tc));
 }
        private template_class CreateTemplateClass(int offset)
        {
            definition_node dn = null;
            if (members.TryGetValue(offset, out dn))
                return dn as template_class;
            template_class tc = null;

            string name = br.ReadString();

            bool is_syn = br.ReadByte() == 1;

            using_namespace_list unl = new using_namespace_list();
            int using_count = br.ReadInt32();
            for (int i = 0; i < using_count; i++)
            {
                unl.AddElement(new using_namespace(br.ReadString()));
            }
            using_namespace_list unl2 = null;
            if (CanReadObject())
            {
                unl2 = new using_namespace_list();
                int using_count2 = br.ReadInt32();
                for (int i = 0; i < using_count2; i++)
                {
                    unl2.AddElement(new using_namespace(br.ReadString()));
                }
            }
            document doc = null;
            if (br.ReadByte() == 1)
            {
                doc = new document(Path.Combine(Path.GetDirectoryName(cur_doc.file_name),br.ReadString()));
            }

            SyntaxTree.SyntaxTreeStreamReader str = new SyntaxTree.SyntaxTreeStreamReader();
            str.br = br;
            SyntaxTree.type_declaration t_d = str._read_node() as SyntaxTree.type_declaration;

            int ext_count = br.ReadInt32();
            List<procedure_definition_info> pdi_list = new List<procedure_definition_info>(ext_count);
            for (int i = 0; i < ext_count; i++)
            {
                byte num = br.ReadByte();
                common_namespace_node c_m_n = cun.namespaces[num];
                SyntaxTree.syntax_tree_node stn = str._read_node();
                SyntaxTree.procedure_definition p_d = stn as SyntaxTree.procedure_definition;
                pdi_list.Add(new procedure_definition_info(c_m_n, p_d));
            }

            //(ssyy) Далее формируем список областей видимости, которые
            //подключаются к модулю. Вообще-то шаблоны классов этим
            //заниматься не должны, но кроме них этот список
            //никому не нужен (по состоянию на 01.06.2007).
            if (cun.scope.TopScopeArray.Length == 0)
            {
                cun.scope.TopScopeArray = MakeTopScopeArray(unl, pcu_file.interface_uses_count);
            }

            if (cun.implementation_scope.TopScopeArray.Length == 0 && unl2 != null)
            {
                //формируем implementation - область
                cun.implementation_scope.TopScopeArray = MakeTopScopeArray(unl2, pcu_file.incl_modules.Length);
            }

            tc = new template_class(t_d, name, cun.namespaces[0], doc, unl);
            tc.external_methods = pdi_list;
            tc.using_list2 = unl2;
            tc.is_synonym = is_syn;

            //members[offset] = tc;
            AddMember(tc, offset);
            
            cun.namespaces[0].scope.AddSymbol(name, new SymbolInfo(tc));

            return tc;
        }
 public SymbolInfo(template_class tc)
 {
     _sym_info = tc;
     _access_level = access_level.al_public;
     _symbol_kind = symbol_kind.sk_none;
 }
        //\ssyy

        //(ssyy) возвращаемое значение заменено на definition_node из-за шаблонов
        public definition_node enter_in_type_method(SyntaxTree.method_name meth_name, string type_name, location loc, int num_template_args)
        {
            // num_template_args - это количество обобщенных аргументов в классе (не в методе!)
            SymbolInfo si = null;

            if (meth_name.ln!=null && meth_name.ln.Count > 1)
            {
                // обработать эту ситуацию особо тщательно: в ln - список возможных пространств имен с классом (возможно, обобщенным) на конце

                // если в ln какое-то имя кроме последнего, содержит обобщенные параметры - это ошибка
                for (var i = 0; i < meth_name.ln.Count - 1; i++)
                    if (meth_name.ln[i] is SyntaxTree.template_type_name)
                        AddError(new NameCannotHaveGenericParameters(meth_name.ln[i].name, syntax_tree_visitor.get_location(meth_name.ln[i]))); 
                
                var ntr = new SyntaxTree.named_type_reference();
                for (var i = 0; i < meth_name.ln.Count; i++)
                    ntr.Add(meth_name.ln[i]);
                if (num_template_args>0 && ! ntr.names[meth_name.ln.Count-1].name.Contains(compiler_string_consts.generic_params_infix))
                {
                     ntr.names[meth_name.ln.Count-1].name += compiler_string_consts.generic_params_infix + num_template_args;
                }
                si = find_definition_node(ntr, loc);
                // если не нашли, то ошибка будет неправильной с неправильным именем - надо исправить
            }
            else
            {
                if (num_template_args != 0)
                {
                    string template_type_name = type_name + compiler_string_consts.generic_params_infix + num_template_args.ToString();
                    si = find(template_type_name);
                    /*if (si == null || si.sym_info.general_node_type != general_node_type.template_type)
                    {
                        type_name = type_name + compiler_string_consts.generic_params_infix + num_template_args.ToString();
                        si = null;
                    }*/
                }
                if (si == null)
                {
                    si = find(type_name);
                }
            }

            if (si == null)
            {
                AddError(new UndefinedNameReference(type_name, loc));
            }
            definition_node dn = si.sym_info;
            if (dn.general_node_type == general_node_type.template_type)
            {
                _ctt = dn as template_class;
                if (_cmn != _ctt.cnn && _ctt.using_list2 == null)
                {
                    //Заполняем список using для внешних методов
                    _ctt.using_list2 = new using_namespace_list();
                    foreach(using_namespace un in syntax_tree_visitor.using_list)
                    {
                        _ctt.using_list2.AddElement(un);
                    }
                }
                return dn;
            }
            if (dn.general_node_type == general_node_type.generic_indicator)
            {
                dn = (dn as generic_indicator).generic;
            }
            if (dn is compiled_type_node)
            {
                _compiled_tn = dn as compiled_type_node;
                return dn;
            }
            if (dn.general_node_type != general_node_type.type_node)
            {
                AddError(loc, "TYPE_NAME_EXPECTED");
            }
#if DEBUG
            if (si.Next != null)
            {
                throw new CompilerInternalError("Must find only type, found some other.");
            }
#endif
            if (dn.semantic_node_type != semantic_node_type.common_type_node)
            {
                AddError(loc, "ONLY_COMMON_TYPE_METHOD_DEFINITION_ALLOWED");
            }

            //TODO: В случае создания вложенных классов этот код надо поправить.
            common_type_node ctn = dn as common_type_node;
            _ctn = ctn;
            return ctn;
        }
 public void reset()
 {
     _cmn = null;
     _ctn = null;
     _func_stack.clear();
     var_defs.Clear();
     _main_procedure = null;
     _last_created_function = null;
     _cycles_stack.clear();
     _num_of_for_cycles = 0;
     _fal = SemanticTree.field_access_level.fal_private;
     rec_num = 1;
     var_defs_stack.Clear();
     type_stack.Clear();
     clear_special_local_vars();
     _scope_stack.Clear();
     TypedFiles.Clear();
     ShortStringTypes.Clear();
     TypedSets.Clear();
     _compiled_tn = null;
     _explicit_interface_type = null;
     _ctt = null;
     allow_inherited_ctor_call = false;
     _types_predefined.Clear();
     _block_stack.Clear();
     member_decls.Clear();
     possible_incorrect_instances.Clear();
     skip_check_where_sections = false;
     LambdaHelper.Reset(); //lroman//
     SavedContext = null;
     SavedContextStack.Clear();
     compiled_tc_cache.Clear();
     extension_method = false;
     _last_created_function = null;
     in_parameters_block = false;
     is_order_independed_method_description = false;
     
 }
        public template_class create_template_class(string name, byte[] tree)
        {
            Dictionary<string, template_class> tc_dict = null;
            template_class tc = null;
            if (compiled_tc_cache.TryGetValue(converted_namespace, out tc_dict) && tc_dict.TryGetValue(name, out tc))
                return tc;

            SyntaxTree.SyntaxTreeStreamReader str = new SyntaxTree.SyntaxTreeStreamReader();
            str.br = new System.IO.BinaryReader(new System.IO.MemoryStream(tree));
            SyntaxTree.type_declaration t_d = str._read_node() as SyntaxTree.type_declaration;
            tc = new template_class(t_d, name, converted_namespace, null, new using_namespace_list());
            tc.is_synonym = true;
            if (tc_dict == null)
            {
                tc_dict = new Dictionary<string, template_class>();
                compiled_tc_cache[converted_namespace] = tc_dict;
            }
            tc_dict[name] = tc;
            return tc;
        }