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); } }
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); }
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(); } } }