//TODO: Если одного из акцессоров нет? public override void visit(SyntaxTree.simple_property _simple_property) { if (_simple_property.accessors == null) AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName); if (_simple_property.property_type == null) AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED"); common_property_node pn = context.add_property(_simple_property.property_name.name, get_location(_simple_property.property_name)); assign_doc_info(pn, _simple_property); //pn.polymorphic_state=SemanticTree.polymorphic_state.ps_common; //pn.loc=get_location(_simple_property.property_name); if (_simple_property.attr == SyntaxTree.definition_attribute.Static) pn.polymorphic_state = SemanticTree.polymorphic_state.ps_static; parameter_list pal_big = new parameter_list(); //TODO: Спросить у Саши как получить тип параметра - var,const и т.д. if (_simple_property.parameter_list != null) { foreach (SyntaxTree.property_parameter pp in _simple_property.parameter_list.parameters) { parameter_list pal_small = new parameter_list(); foreach (SyntaxTree.ident id in pp.names.idents) { common_parameter cp = new common_parameter(id.name, SemanticTree.parameter_type.value, null, concrete_parameter_type.cpt_none, get_location(id)); pal_small.AddElement(cp); } type_node tn = convert_strong(pp.type); foreach (parameter pr in pal_small) { pr.type = tn; } pal_big.AddRange(pal_small); } } pn.parameters.AddRange(pal_big); pn.internal_property_type = convert_strong(_simple_property.property_type); if (_simple_property.accessors != null) { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors); SymbolInfo si = null; //definition_node dn = null; if (_simple_property.accessors.read_accessor != null) { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor); if (_simple_property.accessors.read_accessor.accessor_name == null) { if (!context.converted_type.IsInterface) { AddError(get_location(_simple_property.accessors.read_accessor), "ACCESSOR_NAME_EXPECTED"); } pn.internal_get_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.read_accessor), true); } else { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor.accessor_name); si = context.converted_type.find_in_type(_simple_property.accessors.read_accessor.accessor_name.name, context.CurrentScope); location loc1 = get_location(_simple_property.accessors.read_accessor.accessor_name); if (si == null) { AddError(new UndefinedNameReference(_simple_property.accessors.read_accessor.accessor_name.name, loc1)); } //dn = check_name_node_type(_simple_property.accessors.read_accessor.accessor_name.name, // si, loc1, general_node_type.function_node, general_node_type.variable_node); function_node read_accessor = si.sym_info as function_node; if (read_accessor != null) { bool good_func = true; bool one_func = si.Next == null; while (si != null) { good_func = true; if (read_accessor.parameters.Count != pn.parameters.Count) { good_func = false; if (one_func) { AddError(new PropertyAndReadAccessorParamsCountConvergence(read_accessor, pn, loc1)); } } //TODO: Сверять типы параметров - var, const и т.д. else { for (int i1 = 0; good_func && i1 < read_accessor.parameters.Count; i1++) { if (read_accessor.parameters[i1].parameter_type != pn.parameters[i1].parameter_type || read_accessor.parameters[i1].type != pn.parameters[i1].type) { good_func = false; if (one_func) { AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name, read_accessor.name); } } } if (read_accessor.return_value_type == null) { good_func = false; if (one_func) { AddError(loc1, "PROPERTY_READ_ACCESSOR_CAN_NOT_BE_PROCEDURE"); } } if (read_accessor.return_value_type != pn.property_type) { good_func = false; if (one_func) { AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_RETURN_VALUE_TYPE_CONVERGENCE", pn.name, read_accessor.name); } } if (read_accessor is common_method_node && (read_accessor as common_method_node).is_constructor) { AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } } if (good_func) { break; } si = si.Next; if (si != null) { read_accessor = si.sym_info as function_node; } } if (!good_func) { AddError(loc1, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", read_accessor.name); } read_accessor = GenerateGetMethod(pn,read_accessor as common_method_node,pn.loc); } else { class_field cfield = si.sym_info as class_field; if (cfield == null) { AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } if (_simple_property.parameter_list != null) { AddError(loc1, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); } if (cfield.type != pn.internal_property_type) { AddError(loc1, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); } if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); read_accessor = GenerateGetMethodForField(pn, compiler_string_consts.GetGetAccessorName(pn.name), cfield, loc1); } //Вот здесь уже можем добавить акцессор для чтения. pn.internal_get_function = read_accessor; } if (pn.internal_get_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_get_function.name); if (pn.internal_get_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_get_function.name); } if (_simple_property.accessors.write_accessor != null) { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor); if (_simple_property.accessors.write_accessor.accessor_name == null) { if (!context.converted_type.IsInterface) { AddError(get_location(_simple_property.accessors.write_accessor), "ACCESSOR_NAME_EXPECTED"); } pn.internal_set_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.write_accessor), false); } else { convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor.accessor_name); si = context.converted_type.find_in_type(_simple_property.accessors.write_accessor.accessor_name.name, context.CurrentScope); location loc2 = get_location(_simple_property.accessors.write_accessor.accessor_name); if (si == null) { AddError( new UndefinedNameReference(_simple_property.accessors.write_accessor.accessor_name.name, loc2)); } //dn = check_name_node_type(_simple_property.accessors.write_accessor.accessor_name.name, // si, loc2, general_node_type.function_node, general_node_type.variable_node); function_node write_accessor = si.sym_info as function_node; if (write_accessor != null) { bool good_func = true; bool one_func = si.Next == null; while (si != null) { good_func = true; if (write_accessor.parameters.Count != pn.parameters.Count + 1) { good_func = false; if (one_func) { AddError( new PropertyAndWriteAccessorParamsCountConvergence(write_accessor, pn, loc2)); } } else { //TODO: Сверять типы параметров - var, const и т.д. for (int i2 = 0; good_func && i2 < pn.parameters.Count; i2++) { if (write_accessor.parameters[i2].parameter_type != pn.parameters[i2].parameter_type || write_accessor.parameters[i2].type != pn.parameters[i2].type) { good_func = false; if (one_func) { AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name ,write_accessor.name); } } } if (write_accessor.parameters[write_accessor.parameters.Count - 1].type != pn.property_type || write_accessor.parameters[write_accessor.parameters.Count - 1].parameter_type != PascalABCCompiler.SemanticTree.parameter_type.value) { good_func = false; if (one_func) { AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_LAST_PARAMETER_TYPE_CONVERGENCE", pn.name); } } if (write_accessor.return_value_type != null) { good_func = false; if (one_func) { AddError(loc2, "PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION"); } } } if (good_func) { break; } si = si.Next; if (si != null) { write_accessor = si.sym_info as function_node; } } if (!good_func) { AddError(loc2, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", write_accessor.name); } if (write_accessor is common_method_node && (write_accessor as common_method_node).is_constructor) { AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } write_accessor = GenerateSetMethod(pn, write_accessor as common_method_node, pn.loc); } else { class_field cfield = si.sym_info as class_field; if (cfield == null) { AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); } if (_simple_property.parameter_list != null) { AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); } if (cfield.type != pn.internal_property_type) { AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); } if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2); } //Вот здесь уже можем добавить акцессор для чтения. pn.internal_set_function = write_accessor; } if (pn.internal_set_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_set_function.name); if (pn.internal_set_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_set_function.name); } } make_attributes_for_declaration(_simple_property,pn); //TODO: Можно сделать множество свойств по умолчанию. if (_simple_property.array_default != null) { if (pn.parameters.Count == 0) { AddError(pn.loc, "DEFAULT_PROPERTY_MUST_BE_INDEXED"); } if (context.converted_type.default_property_node != null) { AddError(pn.loc, "DUPLICATE_DEFAULT_PROPERTY_IN_CLASS"); } context.converted_type.default_property = pn; } }
public void init_delegate(common_type_node ctn, type_node return_value_type, parameter_list parameters, location loc) { common_method_node constructor=new common_method_node(compiler_string_consts.default_constructor_name,null,loc,ctn,SemanticTree.polymorphic_state.ps_common, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); constructor.is_constructor = true; constructor.return_value_type = ctn; constructor.function_code=new runtime_statement(SemanticTree.runtime_statement_type.ctor_delegate,loc); common_method_node invoke=new common_method_node(compiler_string_consts.invoke_method_name, return_value_type,loc,ctn,SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.invoke_method_name,new SymbolInfo(invoke)); for (int i=0; i<parameters.Count; i++) { if (parameters[i] is compiled_parameter) { parameters[i] = new common_parameter(parameters[i].name,parameters[i].type,parameters[i].parameter_type,invoke,concrete_parameter_type.cpt_none,null,null); } } invoke.parameters.AddRange(parameters); invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.invoke_delegate, loc); common_method_node begin_invoke = new common_method_node(compiler_string_consts.begin_invoke_method_name, begin_invoke_result_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.begin_invoke_method_name,new SymbolInfo(begin_invoke)); parameter_list begin_invoke_params=new parameter_list(); begin_invoke_params.AddRange(parameters); common_parameter cp=new common_parameter(compiler_string_consts.callback_string,begin_invoke_parameter_type, SemanticTree.parameter_type.value,begin_invoke,concrete_parameter_type.cpt_none, null,loc); begin_invoke_params.AddElement(cp); cp = new common_parameter(compiler_string_consts.object_in_par_string, SystemLibrary.SystemLibrary.object_type, SemanticTree.parameter_type.value,begin_invoke, concrete_parameter_type.cpt_none, null, loc); begin_invoke_params.AddElement(cp); begin_invoke.parameters.AddRange(begin_invoke_params); begin_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.begin_invoke_delegate, loc); common_method_node end_invoke = new common_method_node(compiler_string_consts.end_invoke_method_name, return_value_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public, convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope)); ctn.add_name(compiler_string_consts.end_invoke_method_name,new SymbolInfo(end_invoke)); cp = new common_parameter(compiler_string_consts.result_string, begin_invoke_result_type, SemanticTree.parameter_type.value, end_invoke, concrete_parameter_type.cpt_none, null, loc); end_invoke.parameters.AddElement(cp); end_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.end_invoke_delegate, loc); ctn.methods.AddElement(constructor); ctn.methods.AddElement(invoke); ctn.methods.AddElement(begin_invoke); ctn.methods.AddElement(end_invoke); SystemLibrary.SystemLibrary.init_reference_type(ctn); delegate_internal_interface dii = new delegate_internal_interface(return_value_type, invoke, constructor); dii.parameters.AddRange(parameters); ctn.add_internal_interface(dii); AddOperatorsToDelegate(ctn, loc); }