private void make_attributes_for_declaration(SyntaxTree.unit_module un, common_unit_node cun) { if (cun.attributes != null) { Hashtable ht = new Hashtable(); foreach (SyntaxTree.simple_attribute_list sal in un.attributes.attributes) for (int j = 0; j < sal.attributes.Count; j++) { SyntaxTree.attribute attr = sal.attributes[j]; attribute_converted = true; type_node tn = convert_strong(attr.type); bool is_attr = false; type_node tmp = tn; while (tmp.base_type != null && !is_attr) { is_attr = tmp.base_type == SystemLibrary.SystemLibrary.attribute_type; tmp = tmp.base_type; } if (!is_attr) AddError(get_location(attr), "CLASS_{0}_NOT_ATTRIBUTE", tn.name); bool allowMultiple = false; AttributeTargets targets = get_usage_attrs(tn, out allowMultiple); if (ht.Contains(tn) && !allowMultiple) { AddError(get_location(attr), "DUPLICATE_ATTRIBUTE_{0}_APPLICATION", tn.name); } else ht[tn] = tn; SemanticTree.attribute_qualifier_kind qualifier = SemanticTree.attribute_qualifier_kind.none_kind; if (attr.qualifier != null) if (j == 0) { if (string.Compare(attr.qualifier.name, "return", true) == 0) { if (context.top_function == null) AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD"); if (context.top_function.return_value_type == null || context.top_function.return_value_type == SystemLibrary.SystemLibrary.void_type) AddError(get_location(attr), "EXPECTED_RETURN_VALUE_FOR_ATTRIBUTE"); throw new NotSupportedError(get_location(attr.qualifier)); qualifier = SemanticTree.attribute_qualifier_kind.return_kind; } else throw new NotSupportedError(get_location(attr.qualifier)); } else AddError(get_location(attr.qualifier), "ATTRIBUTE_QUALIFIER_MUST_BE_FIRST"); check_for_usage_attribute(cun, targets, tn.name, get_location(attr), qualifier); attribute_converted = false; SyntaxTree.expression_list cnstr_args = new SyntaxTree.expression_list(); if (attr.arguments != null) { foreach (SyntaxTree.expression e in attr.arguments.expressions) { if (e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident) { break; } else { cnstr_args.expressions.Add(e); } } } expressions_list args = new expressions_list(); for (int i = 0; i < cnstr_args.expressions.Count; i++) { constant_node cn = convert_strong_to_constant_node(cnstr_args.expressions[i]); check_for_strong_constant(cn, get_location(cnstr_args.expressions[i])); args.AddElement(cn); } base_function_call bfc = create_constructor_call(tn, args, get_location(attr)); attribute_node attr_node = new attribute_node(bfc.simple_function_node, tn, get_location(un)); foreach (expression_node en in bfc.parameters) { constant_node cn = convert_strong_to_constant_node(en, en.type); check_for_strong_constant(cn, en.location); attr_node.args.Add(cn); } if (attr.arguments != null) { for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++) { SyntaxTree.expression e = attr.arguments.expressions[i]; if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)) { AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER"); } else { SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident; SymbolInfo si = tn.find(id.name); definition_node dn = context.check_name_node_type(id.name, si, get_location(id), general_node_type.property_node, general_node_type.variable_node); type_node mem_tn = null; if (dn is property_node) { property_node pn = dn as property_node; attr_node.prop_names.Add(pn); if (pn.set_function == null) AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id))); if (pn.set_function.parameters.Count != 1) AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID"); mem_tn = pn.set_function.parameters[0].type; } else if (dn is var_definition_node) { attr_node.field_names.Add(dn as var_definition_node); mem_tn = (dn as var_definition_node).type; } else { throw new CompilerInternalError("Bad general node type for attribute initializer"); } //SyntaxTree.assign tmp_ass = new SyntaxTree.assign(id,(e as SyntaxTree.bin_expr).right,SyntaxTree.Operators.Assignment); //tmp_ass.source_context = e.source_context; //basic_function_call tmp_bfc = convert_strong(tmp_ass) as basic_function_call; constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn); check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right)); if (dn is property_node) attr_node.prop_initializers.Add(cn); else attr_node.field_initializers.Add(cn); } } } attr_node.qualifier = qualifier; cun.attributes.AddElement(attr_node); if (cun.namespaces.Count > 0) cun.namespaces[0].attributes.AddElement(attr_node); } } }
private void SaveAttribute(attribute_node attr) { WriteTypeReference(attr.attribute_type); WriteMethodReference(attr.attribute_constr); bw.Write((byte)attr.qualifier); bw.Write(attr.args.Count); for (int i=0; i<attr.args.Count; i++) VisitExpression(attr.args[i]); bw.Write(attr.prop_names.Count); for (int i=0; i<attr.prop_names.Count; i++) WritePropertyReference(attr.prop_names[i]); bw.Write(attr.field_names.Count); for (int i=0; i<attr.field_names.Count; i++) WriteFieldReference(attr.field_names[i]); bw.Write(attr.prop_initializers.Count); for (int i=0; i<attr.prop_initializers.Count; i++) VisitExpression(attr.prop_initializers[i]); bw.Write(attr.field_initializers.Count); for (int i=0; i<attr.field_initializers.Count; i++) VisitExpression(attr.field_initializers[i]); WriteDebugInfo(attr.location); }
private attribute_node GetAttribute() { type_node tn = GetTypeReference(); function_node fn = GetMethodReference(); SemanticTree.attribute_qualifier_kind quaifier = (SemanticTree.attribute_qualifier_kind)br.ReadByte(); int count = br.ReadInt32(); List<constant_node> args = new List<constant_node>(); for (int i=0; i<count; i++) args.Add((constant_node)CreateExpression()); count = br.ReadInt32(); List<property_node> prop_names = new List<property_node>(); for (int i=0; i<count; i++) prop_names.Add(GetPropertyReference()); count = br.ReadInt32(); List<var_definition_node> field_names = new List<var_definition_node>(); for (int i=0; i<count; i++) field_names.Add(GetFieldReference()); count = br.ReadInt32(); List<constant_node> prop_values = new List<constant_node>(); for (int i=0; i<count; i++) prop_values.Add((constant_node)CreateExpression()); count = br.ReadInt32(); List<constant_node> field_values = new List<constant_node>(); for (int i=0; i<count; i++) field_values.Add((constant_node)CreateExpression()); location loc = ReadDebugInfo(); attribute_node attr = new attribute_node(fn,tn,loc); attr.qualifier = quaifier; attr.args.AddRange(args); attr.prop_names.AddRange(prop_names); attr.field_names.AddRange(field_names); attr.prop_initializers.AddRange(prop_values); attr.field_initializers.AddRange(field_values); return attr; }