2001-11-08 Ravi Pratap <ravi@ximian.com>
[mono.git] / mcs / mcs / attribute.cs
1 //\r
2 // attribute.cs: Attribute Handler\r
3 //\r
4 // Author: Ravi Pratap (ravi@ximian.com)\r
5 //\r
6 // Licensed under the terms of the GNU GPL\r
7 //\r
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)\r
9 //\r
10 //\r
11 \r
12 using System;\r
13 using System.Collections;\r
14 using System.Reflection;\r
15 using System.Reflection.Emit;\r
16 \r
17 namespace CIR {\r
18 \r
19         public class Attribute {\r
20                 \r
21                 public readonly string    Name;\r
22                 public readonly ArrayList Arguments;\r
23 \r
24                 Location Location;\r
25                 \r
26                 public Attribute (string name, ArrayList args, Location loc)\r
27                 {\r
28                         Name = name;\r
29                         Arguments = args;\r
30                         Location = loc;\r
31                 }\r
32 \r
33                 public CustomAttributeBuilder Resolve (EmitContext ec)\r
34                 {\r
35                         string name = Name;\r
36 \r
37                         if (Name.IndexOf ("Attribute") == -1)\r
38                                 name = Name + "Attribute";\r
39                         else if (Name.LastIndexOf ("Attribute") == 0)\r
40                                 name = Name + "Attribute";\r
41                         \r
42                         Type attribute_type = ec.TypeContainer.LookupType (name, false);\r
43 \r
44                         if (attribute_type == null) {\r
45                                 Report.Error (246, Location, "Could not find attribute '" + Name + "' (are you" +\r
46                                               " missing a using directive or an assembly reference ?)");\r
47                                 return null;\r
48                         }\r
49                         \r
50                         // Now we extract the positional and named arguments\r
51                         \r
52                         // FIXME : For now we handle only positional arguments\r
53 \r
54                         if (Arguments != null)\r
55                                 if (Arguments.Count != 1)\r
56                                         Console.WriteLine ("Warning : Cannot handle named arguments in attributes yet");\r
57                         \r
58                         \r
59                         ArrayList pos_args = new ArrayList ();\r
60                         \r
61                         if (Arguments != null)\r
62                                 pos_args = (ArrayList) Arguments [0];\r
63                                 \r
64                         object [] values = new object [pos_args.Count];\r
65                         \r
66                         for (int i = 0; i < pos_args.Count; i++) {\r
67 \r
68                                 Argument a = (Argument) pos_args [i];\r
69 \r
70                                 if (!a.Resolve (ec))\r
71                                         return null;\r
72 \r
73                                 Expression e = Expression.Reduce (ec, a.Expr);\r
74 \r
75                                 if (e is Literal) \r
76                                         values [i] = ((Literal) e).GetValue ();\r
77                                 else { \r
78                                         Report.Error (182, Location,\r
79                                                       "An attribute argument must be a constant expression, typeof " +\r
80                                                       "expression or array creation expression");\r
81                                         return null;\r
82                                 }\r
83                         }\r
84                         \r
85                         Expression mg = Expression.MemberLookup (ec, attribute_type, ".ctor", false,\r
86                                                                  MemberTypes.Constructor,\r
87                                                                  BindingFlags.Public | BindingFlags.Instance,\r
88                                                                  Location);\r
89 \r
90                         if (mg == null) {\r
91                                 Report.Error (-6, Location, "Could not find a constructor for this argument list.");\r
92                                 return null;\r
93                         }\r
94 \r
95                         MethodBase constructor = Invocation.OverloadResolve (ec, (MethodGroupExpr) mg, pos_args, Location);\r
96 \r
97                         if (constructor == null) {\r
98                                 Report.Error (-6, Location, "Could not find a constructor for this argument list.");\r
99                                 return null;\r
100                         }\r
101 \r
102                         CustomAttributeBuilder cb = new CustomAttributeBuilder ((ConstructorInfo) constructor, values); \r
103 \r
104                         return cb;\r
105                 }\r
106 \r
107         }\r
108         \r
109         public class AttributeSection {\r
110                 \r
111                 public readonly string    Target;\r
112                 public readonly ArrayList Attributes;\r
113                 \r
114                 public AttributeSection (string target, ArrayList attrs)\r
115                 {\r
116                         Target = target;\r
117                         Attributes = attrs;\r
118                 }\r
119                 \r
120         }\r
121 \r
122         public class Attributes {\r
123 \r
124                 public ArrayList AttributeSections;\r
125 \r
126                 public Attributes (AttributeSection a)\r
127                 {\r
128                         AttributeSections = new ArrayList ();\r
129                         AttributeSections.Add (a);\r
130 \r
131                 }\r
132 \r
133                 public void AddAttribute (AttributeSection a)\r
134                 {\r
135                         if (a != null)\r
136                                 AttributeSections.Add (a);\r
137                 }\r
138                 \r
139         }\r
140 }\r