~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/nrefactory/ICSharpCode.NRefactory.CSharp/Parser/mcs/enum.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// enum.cs: Enum handling.
 
3
//
 
4
// Author: Miguel de Icaza (miguel@gnu.org)
 
5
//         Ravi Pratap     (ravi@ximian.com)
 
6
//         Marek Safar     (marek.safar@seznam.cz)
 
7
//
 
8
// Dual licensed under the terms of the MIT X11 or GNU GPL
 
9
//
 
10
// Copyright 2001 Ximian, Inc (http://www.ximian.com)
 
11
// Copyright 2003-2003 Novell, Inc (http://www.novell.com)
 
12
// Copyright 2011 Xamarin Inc
 
13
//
 
14
 
 
15
using System;
 
16
 
 
17
#if STATIC
 
18
using MetaType = IKVM.Reflection.Type;
 
19
using IKVM.Reflection;
 
20
#else
 
21
using MetaType = System.Type;
 
22
using System.Reflection;
 
23
#endif
 
24
 
 
25
namespace Mono.CSharp {
 
26
 
 
27
        public class EnumMember : Const
 
28
        {
 
29
                class EnumTypeExpr : TypeExpr
 
30
                {
 
31
                        public override TypeSpec ResolveAsType (IMemberContext ec)
 
32
                        {
 
33
                                type = ec.CurrentType;
 
34
                                eclass = ExprClass.Type;
 
35
                                return type;
 
36
                        }
 
37
                }
 
38
 
 
39
                public EnumMember (Enum parent, MemberName name, Attributes attrs)
 
40
                        : base (parent, new EnumTypeExpr (), Modifiers.PUBLIC, name, attrs)
 
41
                {
 
42
                }
 
43
 
 
44
                static bool IsValidEnumType (TypeSpec t)
 
45
                {
 
46
                        switch (t.BuiltinType) {
 
47
                        case BuiltinTypeSpec.Type.Int:
 
48
                        case BuiltinTypeSpec.Type.UInt:
 
49
                        case BuiltinTypeSpec.Type.Long:
 
50
                        case BuiltinTypeSpec.Type.Byte:
 
51
                        case BuiltinTypeSpec.Type.SByte:
 
52
                        case BuiltinTypeSpec.Type.Short:
 
53
                        case BuiltinTypeSpec.Type.UShort:
 
54
                        case BuiltinTypeSpec.Type.ULong:
 
55
                        case BuiltinTypeSpec.Type.Char:
 
56
                                return true;
 
57
                        default:
 
58
                                return t.IsEnum;
 
59
                        }
 
60
                }
 
61
 
 
62
                public override Constant ConvertInitializer (ResolveContext rc, Constant expr)
 
63
                {
 
64
                        if (expr is EnumConstant)
 
65
                                expr = ((EnumConstant) expr).Child;
 
66
 
 
67
                        var underlying = ((Enum) Parent).UnderlyingType;
 
68
                        if (expr != null) {
 
69
                                expr = expr.ImplicitConversionRequired (rc, underlying, Location);
 
70
                                if (expr != null && !IsValidEnumType (expr.Type)) {
 
71
                                        Enum.Error_1008 (Location, Report);
 
72
                                        expr = null;
 
73
                                }
 
74
                        }
 
75
 
 
76
                        if (expr == null)
 
77
                                expr = New.Constantify (underlying, Location);
 
78
 
 
79
                        return new EnumConstant (expr, MemberType);
 
80
                }
 
81
 
 
82
                public override bool Define ()
 
83
                {
 
84
                        if (!ResolveMemberType ())
 
85
                                return false;
 
86
 
 
87
                        const FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
 
88
                        FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType.GetMetaInfo (), attr);
 
89
                        spec = new ConstSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags, initializer);
 
90
 
 
91
                        Parent.MemberCache.AddMember (spec);
 
92
                        return true;
 
93
                }
 
94
                
 
95
                public override void Accept (StructuralVisitor visitor)
 
96
                {
 
97
                        visitor.Visit (this);
 
98
                }
 
99
 
 
100
        }
 
101
 
 
102
        /// <summary>
 
103
        ///   Enumeration container
 
104
        /// </summary>
 
105
        public class Enum : TypeDefinition
 
106
        {
 
107
                //
 
108
                // Implicit enum member initializer, used when no constant value is provided
 
109
                //
 
110
                sealed class ImplicitInitializer : Expression
 
111
                {
 
112
                        readonly EnumMember prev;
 
113
                        readonly EnumMember current;
 
114
 
 
115
                        public ImplicitInitializer (EnumMember current, EnumMember prev)
 
116
                        {
 
117
                                this.current = current;
 
118
                                this.prev = prev;
 
119
                        }
 
120
 
 
121
                        public override bool ContainsEmitWithAwait ()
 
122
                        {
 
123
                                return false;
 
124
                        }
 
125
 
 
126
                        public override Expression CreateExpressionTree (ResolveContext ec)
 
127
                        {
 
128
                                throw new NotSupportedException ("Missing Resolve call");
 
129
                        }
 
130
 
 
131
                        protected override Expression DoResolve (ResolveContext rc)
 
132
                        {
 
133
                                // We are the first member
 
134
                                if (prev == null) {
 
135
                                        return New.Constantify (current.Parent.Definition, Location);
 
136
                                }
 
137
 
 
138
                                var c = ((ConstSpec) prev.Spec).GetConstant (rc) as EnumConstant;
 
139
                                try {
 
140
                                        return c.Increment ();
 
141
                                } catch (OverflowException) {
 
142
                                        rc.Report.Error (543, current.Location,
 
143
                                                "The enumerator value `{0}' is outside the range of enumerator underlying type `{1}'",
 
144
                                                current.GetSignatureForError (), ((Enum) current.Parent).UnderlyingType.GetSignatureForError ());
 
145
 
 
146
                                        return New.Constantify (current.Parent.Definition, current.Location);
 
147
                                }
 
148
                        }
 
149
 
 
150
                        public override void Emit (EmitContext ec)
 
151
                        {
 
152
                                throw new NotSupportedException ("Missing Resolve call");
 
153
                        }
 
154
                }
 
155
 
 
156
                public static readonly string UnderlyingValueField = "value__";
 
157
 
 
158
                const Modifiers AllowedModifiers =
 
159
                        Modifiers.NEW |
 
160
                        Modifiers.PUBLIC |
 
161
                        Modifiers.PROTECTED |
 
162
                        Modifiers.INTERNAL |
 
163
                        Modifiers.PRIVATE;
 
164
 
 
165
                readonly FullNamedExpression underlying_type_expr;
 
166
 
 
167
                public Enum (TypeContainer parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
 
168
                        : base (parent, name, attrs, MemberKind.Enum)
 
169
                {
 
170
                        underlying_type_expr = type;
 
171
                        var accmods = IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE;
 
172
                        ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod_flags, accmods, Location, Report);
 
173
                        spec = new EnumSpec (null, this, null, null, ModFlags);
 
174
                }
 
175
 
 
176
                #region Properties
 
177
 
 
178
                public override AttributeTargets AttributeTargets {
 
179
                        get {
 
180
                                return AttributeTargets.Enum;
 
181
                        }
 
182
                }
 
183
 
 
184
                public FullNamedExpression BaseTypeExpression {
 
185
                        get {
 
186
                                return underlying_type_expr;
 
187
                        }
 
188
                }
 
189
 
 
190
                protected override TypeAttributes TypeAttr {
 
191
                        get {
 
192
                                return base.TypeAttr | TypeAttributes.Class | TypeAttributes.Sealed;
 
193
                        }
 
194
                }
 
195
 
 
196
                public TypeSpec UnderlyingType {
 
197
                        get {
 
198
                                return ((EnumSpec) spec).UnderlyingType;
 
199
                        }
 
200
                }
 
201
 
 
202
                #endregion
 
203
 
 
204
                public override void Accept (StructuralVisitor visitor)
 
205
                {
 
206
                        visitor.Visit (this);
 
207
                }
 
208
 
 
209
                public void AddEnumMember (EnumMember em)
 
210
                {
 
211
                        if (em.Name == UnderlyingValueField) {
 
212
                                Report.Error (76, em.Location, "An item in an enumeration cannot have an identifier `{0}'",
 
213
                                        UnderlyingValueField);
 
214
                                return;
 
215
                        }
 
216
 
 
217
                        AddMember (em);
 
218
                }
 
219
 
 
220
                public static void Error_1008 (Location loc, Report Report)
 
221
                {
 
222
                        Report.Error (1008, loc,
 
223
                                "Type byte, sbyte, short, ushort, int, uint, long or ulong expected");
 
224
                }
 
225
 
 
226
                protected override void DoDefineContainer ()
 
227
                {
 
228
                        ((EnumSpec) spec).UnderlyingType = underlying_type_expr == null ? Compiler.BuiltinTypes.Int : underlying_type_expr.Type;
 
229
 
 
230
                        TypeBuilder.DefineField (UnderlyingValueField, UnderlyingType.GetMetaInfo (),
 
231
                                FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName);
 
232
 
 
233
                        DefineBaseTypes ();
 
234
                }
 
235
 
 
236
                protected override bool DoDefineMembers ()
 
237
                {
 
238
                        for (int i = 0; i < Members.Count; ++i) {
 
239
                                EnumMember em = (EnumMember) Members[i];
 
240
                                if (em.Initializer == null) {
 
241
                                        em.Initializer = new ImplicitInitializer (em, i == 0 ? null : (EnumMember) Members[i - 1]);
 
242
                                }
 
243
 
 
244
                                em.Define ();
 
245
                        }
 
246
 
 
247
                        return true;
 
248
                }
 
249
 
 
250
                public override bool IsUnmanagedType ()
 
251
                {
 
252
                        return true;
 
253
                }
 
254
 
 
255
                protected override TypeSpec[] ResolveBaseTypes (out FullNamedExpression base_class)
 
256
                {
 
257
                        base_type = Compiler.BuiltinTypes.Enum;
 
258
                        base_class = null;
 
259
                        return null;
 
260
                }
 
261
                
 
262
                protected override bool VerifyClsCompliance ()
 
263
                {
 
264
                        if (!base.VerifyClsCompliance ())
 
265
                                return false;
 
266
 
 
267
                        switch (UnderlyingType.BuiltinType) {
 
268
                        case BuiltinTypeSpec.Type.UInt:
 
269
                        case BuiltinTypeSpec.Type.ULong:
 
270
                        case BuiltinTypeSpec.Type.UShort:
 
271
                                Report.Warning (3009, 1, Location, "`{0}': base type `{1}' is not CLS-compliant",
 
272
                                        GetSignatureForError (), TypeManager.CSharpName (UnderlyingType));
 
273
                                break;
 
274
                        }
 
275
 
 
276
                        return true;
 
277
                }
 
278
        }
 
279
 
 
280
        class EnumSpec : TypeSpec
 
281
        {
 
282
                TypeSpec underlying;
 
283
 
 
284
                public EnumSpec (TypeSpec declaringType, ITypeDefinition definition, TypeSpec underlyingType, MetaType info, Modifiers modifiers)
 
285
                        : base (MemberKind.Enum, declaringType, definition, info, modifiers | Modifiers.SEALED)
 
286
                {
 
287
                        this.underlying = underlyingType;
 
288
                }
 
289
 
 
290
                public TypeSpec UnderlyingType {
 
291
                        get {
 
292
                                return underlying;
 
293
                        }
 
294
                        set {
 
295
                                if (underlying != null)
 
296
                                        throw new InternalErrorException ("UnderlyingType reset");
 
297
 
 
298
                                underlying = value;
 
299
                        }
 
300
                }
 
301
 
 
302
                public static TypeSpec GetUnderlyingType (TypeSpec t)
 
303
                {
 
304
                        return ((EnumSpec) t.GetDefinition ()).UnderlyingType;
 
305
                }
 
306
 
 
307
                public static bool IsValidUnderlyingType (TypeSpec type)
 
308
                {
 
309
                        switch (type.BuiltinType) {
 
310
                        case BuiltinTypeSpec.Type.Int:
 
311
                        case BuiltinTypeSpec.Type.UInt:
 
312
                        case BuiltinTypeSpec.Type.Long:
 
313
                        case BuiltinTypeSpec.Type.Byte:
 
314
                        case BuiltinTypeSpec.Type.SByte:
 
315
                        case BuiltinTypeSpec.Type.Short:
 
316
                        case BuiltinTypeSpec.Type.UShort:
 
317
                        case BuiltinTypeSpec.Type.ULong:
 
318
                                return true;
 
319
                        }
 
320
 
 
321
                        return false;
 
322
                }
 
323
        }
 
324
}