コード例 #1
0
        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);
            }
        }
コード例 #2
0
 private void VisitTypeSynonym(type_synonym synonym)
 {
     bw.Write(synonym.name);
     int pos = (int)bw.BaseStream.Position;
     bw.Write(0);
     WriteTypeReference(synonym.original_type);
     WriteDebugInfo(synonym.Location);
     int next_pos = (int)bw.BaseStream.Position;
     bw.BaseStream.Seek(pos, SeekOrigin.Begin);
     bw.Write(next_pos-pos);
     bw.BaseStream.Seek(next_pos, SeekOrigin.Begin);
 }
コード例 #3
0
ファイル: DocXml.cs プロジェクト: lisiynos/pascalabcnet
		private void SaveTypeSynonim(type_synonym ctn)
		{
			if (!string.IsNullOrEmpty(ctn.documentation))
			{
				if (!ctn.documentation.Trim(' ','\t').StartsWith("<summary>"))
				{
					xtw.WriteStartElement("member");
					xtw.WriteStartAttribute("name");
					xtw.WriteString("T:"+ctn.name);
					xtw.WriteEndAttribute();
					xtw.WriteStartElement("summary");
					xtw.WriteString(ctn.documentation);
					xtw.WriteEndElement();
					xtw.WriteEndElement();
				}
				else
				{
					string doc = string.Concat("<member name=\""+"T:"+ctn.name+"\">",ctn.documentation,"</member>");
					StringReader sr = new StringReader(doc);
					XmlReader xr = XmlTextReader.Create(sr);
					xr.Read();
					xtw.WriteNode(xr.ReadSubtree(),false);
					sr.Close();
					xr.Close();
				}
			}
		}