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

« back to all changes in this revision

Viewing changes to contrib/NRefactory/Project/Src/Parser/CSharp/CSharpParser.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
 
// <file>
2
 
//     <copyright see="prj:///doc/copyright.txt"/>
3
 
//     <license see="prj:///doc/license.txt"/>
4
 
//     <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
5
 
//     <version>$Revision: 4740 $</version>
6
 
// </file>
7
 
 
8
 
using ICSharpCode.OldNRefactory.Visitors;
9
 
using System;
10
 
using System.Collections.Generic;
11
 
using System.Diagnostics;
12
 
using System.Text;
13
 
using ICSharpCode.OldNRefactory.Ast;
14
 
 
15
 
namespace ICSharpCode.OldNRefactory.Parser.CSharp
16
 
{
17
 
        internal sealed partial class Parser : AbstractParser
18
 
        {
19
 
                Lexer lexer;
20
 
                
21
 
                public Parser(ILexer lexer) : base(lexer)
22
 
                {
23
 
                        this.lexer = (Lexer)lexer;
24
 
                        // due to anonymous methods, we always need a compilation unit, so
25
 
                        // create it in the constructor
26
 
                        compilationUnit = new CompilationUnit();
27
 
                }
28
 
                
29
 
                StringBuilder qualidentBuilder = new StringBuilder();
30
 
 
31
 
                Token t {
32
 
                        [System.Diagnostics.DebuggerStepThrough]
33
 
                        get {
34
 
                                return lexer.Token;
35
 
                        }
36
 
                }
37
 
 
38
 
                Token la {
39
 
                        [System.Diagnostics.DebuggerStepThrough]
40
 
                        get {
41
 
                                return lexer.LookAhead;
42
 
                        }
43
 
                }
44
 
 
45
 
                public void Error(string s)
46
 
                {
47
 
                        if (errDist >= MinErrDist) {
48
 
                                this.Errors.Error(la.line, la.col, s);
49
 
                        }
50
 
                        errDist = 0;
51
 
                }
52
 
 
53
 
                public override void Parse()
54
 
                {
55
 
                        ParseRoot();
56
 
                        compilationUnit.AcceptVisitor(new SetParentVisitor(), null);
57
 
                }
58
 
                
59
 
                public override TypeReference ParseTypeReference ()
60
 
                {
61
 
                        lexer.NextToken();
62
 
                        TypeReference type;
63
 
                        Type(out type);
64
 
                        return type;
65
 
                }
66
 
 
67
 
                public override Expression ParseExpression()
68
 
                {
69
 
                        lexer.NextToken();
70
 
                        Location startLocation = la.Location;
71
 
                        Expression expr;
72
 
                        Expr(out expr);
73
 
                        // SEMICOLON HACK : without a trailing semicolon, parsing expressions does not work correctly
74
 
                        if (la.kind == Tokens.Semicolon) lexer.NextToken();
75
 
                        if (expr != null) {
76
 
                                expr.StartLocation = startLocation;
77
 
                                expr.EndLocation = t.EndLocation;
78
 
                                expr.AcceptVisitor(new SetParentVisitor(), null);
79
 
                        }
80
 
                        Expect(Tokens.EOF);
81
 
                        return expr;
82
 
                }
83
 
                
84
 
                public override BlockStatement ParseBlock()
85
 
                {
86
 
                        lexer.NextToken();
87
 
                        compilationUnit = new CompilationUnit();
88
 
                        
89
 
                        BlockStatement blockStmt = new BlockStatement();
90
 
                        blockStmt.StartLocation = la.Location;
91
 
                        compilationUnit.BlockStart(blockStmt);
92
 
                        
93
 
                        while (la.kind != Tokens.EOF) {
94
 
                                Token oldLa = la;
95
 
                                Statement();
96
 
                                if (la == oldLa) {
97
 
                                        // did not advance lexer position, we cannot parse this as a statement block
98
 
                                        return null;
99
 
                                }
100
 
                        }
101
 
                        
102
 
                        compilationUnit.BlockEnd();
103
 
                        blockStmt.EndLocation = t.EndLocation;
104
 
                        Expect(Tokens.EOF);
105
 
                        blockStmt.AcceptVisitor(new SetParentVisitor(), null);
106
 
                        return blockStmt;
107
 
                }
108
 
                
109
 
                public override List<INode> ParseTypeMembers()
110
 
                {
111
 
                        lexer.NextToken();
112
 
                        compilationUnit = new CompilationUnit();
113
 
                        
114
 
                        TypeDeclaration newType = new TypeDeclaration(Modifiers.None, null);
115
 
                        compilationUnit.BlockStart(newType);
116
 
                        ClassBody();
117
 
                        compilationUnit.BlockEnd();
118
 
                        Expect(Tokens.EOF);
119
 
                        newType.AcceptVisitor(new SetParentVisitor(), null);
120
 
                        return newType.Children;
121
 
                }
122
 
                
123
 
                // Begin ISTypeCast
124
 
                bool IsTypeCast()
125
 
                {
126
 
                        if (la.kind != Tokens.OpenParenthesis) {
127
 
                                return false;
128
 
                        }
129
 
                        bool isPossibleExpression = true;
130
 
                        
131
 
                        lexer.StartPeek();
132
 
                        Token pt = lexer.Peek();
133
 
                        
134
 
                        if (!IsTypeNameOrKWForTypeCast(ref pt, ref isPossibleExpression)) {
135
 
                                return false;
136
 
                        }
137
 
                        
138
 
                        // ")"
139
 
                        if (pt.kind != Tokens.CloseParenthesis) {
140
 
                                return false;
141
 
                        }
142
 
                        if (isPossibleExpression) {
143
 
                                // check successor
144
 
                                pt = lexer.Peek();
145
 
                                return Tokens.CastFollower[pt.kind];
146
 
                        } else {
147
 
                                // not possibly an expression: don't check cast follower
148
 
                                return true;
149
 
                        }
150
 
                }
151
 
 
152
 
                /* !!! Proceeds from current peek position !!! */
153
 
                bool IsTypeKWForTypeCast(ref Token pt)
154
 
                {
155
 
                        if (Tokens.TypeKW[pt.kind]) {
156
 
                                pt = lexer.Peek();
157
 
                                return IsPointerOrDims(ref pt) && SkipQuestionMark(ref pt);
158
 
                        } else if (pt.kind == Tokens.Void) {
159
 
                                pt = lexer.Peek();
160
 
                                return IsPointerOrDims(ref pt);
161
 
                        }
162
 
                        return false;
163
 
                }
164
 
 
165
 
                /* !!! Proceeds from current peek position !!! */
166
 
                bool IsTypeNameOrKWForTypeCast(ref Token pt, ref bool isPossibleExpression)
167
 
                {
168
 
                        if (Tokens.TypeKW[pt.kind] || pt.kind == Tokens.Void) {
169
 
                                isPossibleExpression = false;
170
 
                                return IsTypeKWForTypeCast(ref pt);
171
 
                        } else {
172
 
                                return IsTypeNameForTypeCast(ref pt, ref isPossibleExpression);
173
 
                        }
174
 
                }
175
 
                
176
 
                bool IsTypeNameOrKWForTypeCast(ref Token pt)
177
 
                {
178
 
                        bool tmp = false;
179
 
                        return IsTypeNameOrKWForTypeCast(ref pt, ref tmp);
180
 
                }
181
 
 
182
 
                // TypeName = ident [ "::" ident ] { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident } ["?"] PointerOrDims
183
 
                /* !!! Proceeds from current peek position !!! */
184
 
                bool IsTypeNameForTypeCast(ref Token pt, ref bool isPossibleExpression)
185
 
                {
186
 
                        // ident
187
 
                        if (!IsIdentifierToken(pt)) {
188
 
                                return false;
189
 
                        }
190
 
                        pt = Peek();
191
 
                        // "::" ident
192
 
                        if (pt.kind == Tokens.DoubleColon) {
193
 
                                pt = Peek();
194
 
                                if (!IsIdentifierToken(pt)) {
195
 
                                        return false;
196
 
                                }
197
 
                                pt = Peek();
198
 
                        }
199
 
                        // { ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] "." ident }
200
 
                        while (true) {
201
 
                                if (pt.kind == Tokens.LessThan) {
202
 
                                        do {
203
 
                                                pt = Peek();
204
 
                                                if (!IsTypeNameOrKWForTypeCast(ref pt)) {
205
 
                                                        return false;
206
 
                                                }
207
 
                                        } while (pt.kind == Tokens.Comma);
208
 
                                        if (pt.kind != Tokens.GreaterThan) {
209
 
                                                return false;
210
 
                                        }
211
 
                                        pt = Peek();
212
 
                                }
213
 
                                if (pt.kind != Tokens.Dot)
214
 
                                        break;
215
 
                                pt = Peek();
216
 
                                if (pt.kind != Tokens.Identifier) {
217
 
                                        return false;
218
 
                                }
219
 
                                pt = Peek();
220
 
                        }
221
 
                        // ["?"]
222
 
                        if (pt.kind == Tokens.Question) {
223
 
                                pt = Peek();
224
 
                        }
225
 
                        if (pt.kind == Tokens.Times || pt.kind == Tokens.OpenSquareBracket) {
226
 
                                isPossibleExpression = false;
227
 
                                return IsPointerOrDims(ref pt);
228
 
                        }
229
 
                        return true;
230
 
                }
231
 
                // END IsTypeCast
232
 
                
233
 
                // Gets if the token is a possible token for an expression start
234
 
                // Is used to determine if "a is Type ? token" a the start of a ternary
235
 
                // expression or a type test for Nullable<Type>
236
 
                bool IsPossibleExpressionStart(int token)
237
 
                {
238
 
                        return Tokens.CastFollower[token] || Tokens.UnaryOp[token];
239
 
                }
240
 
                
241
 
                // ( { [TypeNameOrKWForTypeCast] ident "," } )
242
 
                bool IsLambdaExpression()
243
 
                {
244
 
                        if (la.kind != Tokens.OpenParenthesis) {
245
 
                                return false;
246
 
                        }
247
 
                        StartPeek();
248
 
                        Token pt = Peek();
249
 
                        while (pt.kind != Tokens.CloseParenthesis) {
250
 
                                if (pt.kind == Tokens.Out || pt.kind == Tokens.Ref) {
251
 
                                        pt = Peek();
252
 
                                }
253
 
                                if (!IsTypeNameOrKWForTypeCast(ref pt)) {
254
 
                                        return false;
255
 
                                }
256
 
                                if (IsIdentifierToken(pt)) {
257
 
                                        // make ident optional: if implicitly typed lambda arguments are used, IsTypeNameForTypeCast
258
 
                                        // has already accepted the identifier
259
 
                                        pt = Peek();
260
 
                                }
261
 
                                if (pt.kind == Tokens.CloseParenthesis) {
262
 
                                        break;
263
 
                                }
264
 
                                // require comma between parameters:
265
 
                                if (pt.kind == Tokens.Comma) {
266
 
                                        pt = Peek();
267
 
                                } else {
268
 
                                        return false;
269
 
                                }
270
 
                        }
271
 
                        pt = Peek();
272
 
                        return pt.kind == Tokens.LambdaArrow;
273
 
                }
274
 
 
275
 
                /* Checks whether the next sequences of tokens is a qualident *
276
 
                 * and returns the qualident string                           */
277
 
                /* !!! Proceeds from current peek position !!! */
278
 
                bool IsQualident(ref Token pt, out string qualident)
279
 
                {
280
 
                        if (IsIdentifierToken(pt)) {
281
 
                                qualidentBuilder.Length = 0; qualidentBuilder.Append(pt.val);
282
 
                                pt = Peek();
283
 
                                while (pt.kind == Tokens.Dot || pt.kind == Tokens.DoubleColon) {
284
 
                                        pt = Peek();
285
 
                                        if (!IsIdentifierToken(pt)) {
286
 
                                                qualident = String.Empty;
287
 
                                                return false;
288
 
                                        }
289
 
                                        qualidentBuilder.Append('.');
290
 
                                        qualidentBuilder.Append(pt.val);
291
 
                                        pt = Peek();
292
 
                                }
293
 
                                qualident = qualidentBuilder.ToString();
294
 
                                return true;
295
 
                        }
296
 
                        qualident = String.Empty;
297
 
                        return false;
298
 
                }
299
 
 
300
 
                /* Skips generic type extensions */
301
 
                /* !!! Proceeds from current peek position !!! */
302
 
 
303
 
                /* skip: { "*" | "[" { "," } "]" } */
304
 
                /* !!! Proceeds from current peek position !!! */
305
 
                bool IsPointerOrDims (ref Token pt)
306
 
                {
307
 
                        for (;;) {
308
 
                                if (pt.kind == Tokens.OpenSquareBracket) {
309
 
                                        do pt = Peek();
310
 
                                        while (pt.kind == Tokens.Comma);
311
 
                                        if (pt.kind != Tokens.CloseSquareBracket) return false;
312
 
                                } else if (pt.kind != Tokens.Times) break;
313
 
                                pt = Peek();
314
 
                        }
315
 
                        return true;
316
 
                }
317
 
 
318
 
                /* Return the n-th token after the current lookahead token */
319
 
                void StartPeek()
320
 
                {
321
 
                        lexer.StartPeek();
322
 
                }
323
 
 
324
 
                Token Peek()
325
 
                {
326
 
                        return lexer.Peek();
327
 
                }
328
 
 
329
 
                Token Peek (int n)
330
 
                {
331
 
                        lexer.StartPeek();
332
 
                        Token x = la;
333
 
                        while (n > 0) {
334
 
                                x = lexer.Peek();
335
 
                                n--;
336
 
                        }
337
 
                        return x;
338
 
                }
339
 
 
340
 
                /*-----------------------------------------------------------------*
341
 
                 * Resolver routines to resolve LL(1) conflicts:                   *                                                  *
342
 
                 * These resolution routine return a boolean value that indicates  *
343
 
                 * whether the alternative at hand shall be choosen or not.        *
344
 
                 * They are used in IF ( ... ) expressions.                        *
345
 
                 *-----------------------------------------------------------------*/
346
 
 
347
 
                /* True, if ident is followed by "=" */
348
 
                bool IdentAndAsgn ()
349
 
                {
350
 
                        return IsIdentifierToken(la) && Peek(1).kind == Tokens.Assign;
351
 
                }
352
 
                
353
 
                bool IdentAndDoubleColon ()
354
 
                {
355
 
                        return IsIdentifierToken(la) && Peek(1).kind == Tokens.DoubleColon;
356
 
                }
357
 
 
358
 
                bool IsAssignment () { return IdentAndAsgn(); }
359
 
 
360
 
                /* True, if ident is followed by ",", "=", "[" or ";" */
361
 
                bool IsVarDecl () {
362
 
                        int peek = Peek(1).kind;
363
 
                        return IsIdentifierToken(la) &&
364
 
                                (peek == Tokens.Comma || peek == Tokens.Assign || peek == Tokens.Semicolon || peek == Tokens.OpenSquareBracket);
365
 
                }
366
 
 
367
 
                /* True, if the comma is not a trailing one, *
368
 
                 * like the last one in: a, b, c,            */
369
 
                bool NotFinalComma () {
370
 
                        int peek = Peek(1).kind;
371
 
                        return la.kind == Tokens.Comma &&
372
 
                                peek != Tokens.CloseCurlyBrace && peek != Tokens.CloseSquareBracket;
373
 
                }
374
 
 
375
 
                /* True, if "void" is followed by "*" */
376
 
                bool NotVoidPointer () {
377
 
                        return la.kind == Tokens.Void && Peek(1).kind != Tokens.Times;
378
 
                }
379
 
 
380
 
                /* True, if "checked" or "unchecked" are followed by "{" */
381
 
                bool UnCheckedAndLBrace () {
382
 
                        return la.kind == Tokens.Checked || la.kind == Tokens.Unchecked &&
383
 
                                Peek(1).kind == Tokens.OpenCurlyBrace;
384
 
                }
385
 
 
386
 
                /* True, if "." is followed by an ident */
387
 
                bool DotAndIdent () {
388
 
                        return la.kind == Tokens.Dot && IsIdentifierToken(Peek(1));
389
 
                }
390
 
 
391
 
                /* True, if ident is followed by ":" */
392
 
                bool IdentAndColon () {
393
 
                        return IsIdentifierToken(la) && Peek(1).kind == Tokens.Colon;
394
 
                }
395
 
 
396
 
                bool IsLabel () { return IdentAndColon(); }
397
 
 
398
 
                /* True, if ident is followed by "(" */
399
 
                bool IdentAndLPar () {
400
 
                        return IsIdentifierToken(la) && Peek(1).kind == Tokens.OpenParenthesis;
401
 
                }
402
 
 
403
 
                /* True, if "catch" is followed by "(" */
404
 
                bool CatchAndLPar () {
405
 
                        return la.kind == Tokens.Catch && Peek(1).kind == Tokens.OpenParenthesis;
406
 
                }
407
 
                bool IsTypedCatch () { return CatchAndLPar(); }
408
 
 
409
 
                /* True, if "[" is followed by the ident "assembly" */
410
 
                bool IsGlobalAttrTarget () {
411
 
                        Token pt = Peek(1);
412
 
                        return la.kind == Tokens.OpenSquareBracket &&
413
 
                                IsIdentifierToken(pt) && (pt.val == "assembly" || pt.val == "module");
414
 
                }
415
 
 
416
 
                /* True, if "[" is followed by "," or "]" */
417
 
                bool LBrackAndCommaOrRBrack () {
418
 
                        int peek = Peek(1).kind;
419
 
                        return la.kind == Tokens.OpenSquareBracket &&
420
 
                                (peek == Tokens.Comma || peek == Tokens.CloseSquareBracket);
421
 
                }
422
 
 
423
 
                /* True, if "[" is followed by "," or "]" */
424
 
                /* or if the current token is "*"         */
425
 
                bool TimesOrLBrackAndCommaOrRBrack () {
426
 
                        return la.kind == Tokens.Times || LBrackAndCommaOrRBrack();
427
 
                }
428
 
                bool IsPointerOrDims () { return TimesOrLBrackAndCommaOrRBrack(); }
429
 
                bool IsPointer () { return la.kind == Tokens.Times; }
430
 
 
431
 
 
432
 
                bool SkipGeneric(ref Token pt)
433
 
                {
434
 
                        if (pt.kind == Tokens.LessThan) {
435
 
                                do {
436
 
                                        pt = Peek();
437
 
                                        if (!IsTypeNameOrKWForTypeCast(ref pt)) return false;
438
 
                                } while (pt.kind == Tokens.Comma);
439
 
                                if (pt.kind != Tokens.GreaterThan) return false;
440
 
                                pt = Peek();
441
 
                        }
442
 
                        return true;
443
 
                }
444
 
                bool SkipQuestionMark(ref Token pt)
445
 
                {
446
 
                        if (pt.kind == Tokens.Question) {
447
 
                                pt = Peek();
448
 
                        }
449
 
                        return true;
450
 
                }
451
 
 
452
 
                /* True, if lookahead is a primitive type keyword, or */
453
 
                /* if it is a type declaration followed by an ident   */
454
 
                bool IsLocalVarDecl ()
455
 
                {
456
 
                        if (IsYieldStatement ()) {
457
 
                                return false;
458
 
                        }
459
 
                        
460
 
                        if ((Tokens.TypeKW[la.kind] && Peek (1).kind != Tokens.Dot) || la.kind == Tokens.Void) {
461
 
                                return true;
462
 
                        }
463
 
                        
464
 
                        StartPeek ();
465
 
                        Token pt = la;
466
 
                        bool result = IsTypeNameOrKWForTypeCast (ref pt) && IsIdentifierToken (pt);
467
 
                        if (Peek (1).kind == Tokens.Question) {
468
 
                                if (Peek (2).kind == Tokens.OpenSquareBracket) // array case: T?[,]
469
 
                                        return true;
470
 
                                result &= Peek (2).kind == Tokens.Identifier;
471
 
                                result &= Peek (3).kind == Tokens.Semicolon || Peek (3).kind == Tokens.Comma || Peek (3).kind == Tokens.Assign;
472
 
                        }
473
 
                        return result;
474
 
                }
475
 
 
476
 
                /* True if lookahead is a type argument list (<...>) followed by
477
 
                 * one of "(  )  ]  }  :  ;  ,  .  ?  ==  !=" */
478
 
                bool IsGenericInSimpleNameOrMemberAccess()
479
 
                {
480
 
                        Token t = la;
481
 
                        if (t.kind != Tokens.LessThan) return false;
482
 
                        StartPeek();
483
 
                        return SkipGeneric(ref t) && Tokens.GenericFollower[t.kind];
484
 
                }
485
 
 
486
 
                bool IsExplicitInterfaceImplementation()
487
 
                {
488
 
                        StartPeek();
489
 
                        Token pt = la;
490
 
                        pt = Peek();
491
 
                        if (pt.kind == Tokens.Dot || pt.kind == Tokens.DoubleColon)
492
 
                                return true;
493
 
                        if (pt.kind == Tokens.LessThan) {
494
 
                                if (SkipGeneric(ref pt))
495
 
                                        return pt.kind == Tokens.Dot;
496
 
                        }
497
 
                        return false;
498
 
                }
499
 
 
500
 
                /* True, if lookahead ident is "yield" and than follows a break or return */
501
 
                bool IsYieldStatement () {
502
 
                        return la.kind == Tokens.Yield && (Peek(1).kind == Tokens.Return || Peek(1).kind == Tokens.Break);
503
 
                }
504
 
 
505
 
                /* True, if lookahead is a local attribute target specifier, *
506
 
                 * i.e. one of "event", "return", "field", "method",         *
507
 
                 *             "module", "param", "property", or "type"      */
508
 
                bool IsLocalAttrTarget () {
509
 
                        int cur = la.kind;
510
 
                        string val = la.val;
511
 
 
512
 
                        return (cur == Tokens.Event || cur == Tokens.Return ||
513
 
                                (Tokens.IdentifierTokens[cur] &&
514
 
                                 (val == "field" || val == "method"   || val == "module" ||
515
 
                                  val == "param" || val == "property" || val == "type"))) &&
516
 
                                Peek(1).kind == Tokens.Colon;
517
 
                }
518
 
 
519
 
                bool IsShiftRight()
520
 
                {
521
 
                        Token next = Peek(1);
522
 
                        // TODO : Add col test (seems not to work, lexer bug...) :  && la.col == next.col - 1
523
 
                        return (la.kind == Tokens.GreaterThan && next.kind == Tokens.GreaterThan);
524
 
                }
525
 
 
526
 
                bool IsGenericExpression(Expression expr)
527
 
                {
528
 
                        if (expr is IdentifierExpression)
529
 
                                return ((IdentifierExpression)expr).TypeArguments.Count > 0;
530
 
                        else if (expr is MemberReferenceExpression)
531
 
                                return ((MemberReferenceExpression)expr).TypeArguments.Count > 0;
532
 
                        else
533
 
                                return false;
534
 
                }
535
 
 
536
 
                bool ShouldConvertTargetExpressionToTypeReference(Expression targetExpr)
537
 
                {
538
 
                        if (targetExpr is IdentifierExpression)
539
 
                                return ((IdentifierExpression)targetExpr).TypeArguments.Count > 0;
540
 
                        else if (targetExpr is MemberReferenceExpression)
541
 
                                return ((MemberReferenceExpression)targetExpr).TypeArguments.Count > 0;
542
 
                        else
543
 
                                return false;
544
 
                }
545
 
                
546
 
                TypeReference GetTypeReferenceFromExpression(Expression expr)
547
 
                {
548
 
                        if (expr is TypeReferenceExpression)
549
 
                                return (expr as TypeReferenceExpression).TypeReference;
550
 
                        
551
 
                        IdentifierExpression ident = expr as IdentifierExpression;
552
 
                        if (ident != null) {
553
 
                                return new TypeReference(ident.Identifier, ident.TypeArguments);
554
 
                        }
555
 
                        
556
 
                        MemberReferenceExpression member = expr as MemberReferenceExpression;
557
 
                        if (member != null) {
558
 
                                TypeReference targetType = GetTypeReferenceFromExpression(member.TargetObject);
559
 
                                if (targetType != null) {
560
 
                                        if (targetType.GenericTypes.Count == 0 && targetType.IsArrayType == false) {
561
 
                                                TypeReference tr = new TypeReference(targetType.Type + "." + member.MemberName, member.TypeArguments);
562
 
                                                tr.IsGlobal = targetType.IsGlobal;
563
 
                                                return tr;
564
 
                                        } else {
565
 
                                                return new InnerClassTypeReference(targetType, member.MemberName, member.TypeArguments);
566
 
                                        }
567
 
                                }
568
 
                        }
569
 
                        return null;
570
 
                }
571
 
                
572
 
                bool IsMostNegativeIntegerWithoutTypeSuffix()
573
 
                {
574
 
                        Token token = la;
575
 
                        if (token.kind == Tokens.Literal) {
576
 
                                return token.val == "2147483648" || token.val == "9223372036854775808";
577
 
                        } else {
578
 
                                return false;
579
 
                        }
580
 
                }
581
 
                
582
 
                bool LastExpressionIsUnaryMinus(System.Collections.ArrayList expressions)
583
 
                {
584
 
                        if (expressions.Count == 0) return false;
585
 
                        UnaryOperatorExpression uoe = expressions[expressions.Count - 1] as UnaryOperatorExpression;
586
 
                        if (uoe != null) {
587
 
                                return uoe.Op == UnaryOperatorType.Minus;
588
 
                        } else {
589
 
                                return false;
590
 
                        }
591
 
                }
592
 
                
593
 
                bool StartOfQueryExpression()
594
 
                {
595
 
                        if (la.kind == Tokens.From) {
596
 
                                Token p = Peek(1);
597
 
                                if (IsIdentifierToken(p) || Tokens.TypeKW[p.kind])
598
 
                                        return true;
599
 
                        }
600
 
                        return false;
601
 
                }
602
 
                
603
 
                static bool IsIdentifierToken(Token tk)
604
 
                {
605
 
                        return Tokens.IdentifierTokens[tk.kind];
606
 
                }
607
 
                
608
 
                /// <summary>
609
 
                /// Adds a child item to a collection stored in the parent node.
610
 
                /// Also set's the item's parent to <paramref name="parent"/>.
611
 
                /// Does nothing if item is null.
612
 
                /// </summary>
613
 
                static void SafeAdd<T>(INode parent, List<T> list, T item) where T : class, INode
614
 
                {
615
 
                        Debug.Assert(parent != null);
616
 
                        Debug.Assert((parent is INullable) ? !(parent as INullable).IsNull : true);
617
 
                        if (item != null) {
618
 
                                list.Add(item);
619
 
                                item.Parent = parent;
620
 
                        }
621
 
                }
622
 
                
623
 
                internal static string GetReflectionNameForOperator(OverloadableOperatorType op)
624
 
                {
625
 
                        switch (op) {
626
 
                                case OverloadableOperatorType.None:
627
 
                                        return "op_unknown";
628
 
                                case OverloadableOperatorType.Add:
629
 
                                        return "op_Addition";
630
 
                                case OverloadableOperatorType.BitNot:
631
 
                                        return "op_OnesComplement";
632
 
                                case OverloadableOperatorType.BitwiseAnd:
633
 
                                        return "op_BitwiseAnd";
634
 
                                case OverloadableOperatorType.BitwiseOr:
635
 
                                        return "op_BitwiseOr";
636
 
                                case OverloadableOperatorType.Concat:
637
 
                                case OverloadableOperatorType.CType:
638
 
                                        return "op_unknown";
639
 
                                case OverloadableOperatorType.Decrement:
640
 
                                        return "op_Decrement";
641
 
                                case OverloadableOperatorType.Divide:
642
 
                                        return "op_Division";
643
 
                                case OverloadableOperatorType.DivideInteger:
644
 
                                        return "op_unknown";
645
 
                                case OverloadableOperatorType.Equality:
646
 
                                        return "op_Equality";
647
 
                                case OverloadableOperatorType.ExclusiveOr:
648
 
                                        return "op_ExclusiveOr";
649
 
                                case OverloadableOperatorType.GreaterThan:
650
 
                                        return "op_GreaterThan";
651
 
                                case OverloadableOperatorType.GreaterThanOrEqual:
652
 
                                        return "op_GreaterThanOrEqual";
653
 
                                case OverloadableOperatorType.Increment:
654
 
                                        return "op_Increment";
655
 
                                case OverloadableOperatorType.InEquality:
656
 
                                        return "op_Inequality";
657
 
                                case OverloadableOperatorType.IsFalse:
658
 
                                        return "op_False";
659
 
                                case OverloadableOperatorType.IsTrue:
660
 
                                        return "op_True";
661
 
                                case OverloadableOperatorType.LessThan:
662
 
                                        return "op_LessThan";
663
 
                                case OverloadableOperatorType.LessThanOrEqual:
664
 
                                        return "op_LessThanOrEqual";
665
 
                                case OverloadableOperatorType.Like:
666
 
                                        return "op_unknown";
667
 
                                case OverloadableOperatorType.Modulus:
668
 
                                        return "op_Modulus";
669
 
                                case OverloadableOperatorType.Multiply:
670
 
                                        return "op_Multiply";
671
 
                                case OverloadableOperatorType.Not:
672
 
                                        return "op_LogicalNot";
673
 
                                case OverloadableOperatorType.Power:
674
 
                                        return "op_unknown";
675
 
                                case OverloadableOperatorType.ShiftLeft:
676
 
                                        return "op_LeftShift";
677
 
                                case OverloadableOperatorType.ShiftRight:
678
 
                                        return "op_RightShift";
679
 
                                case OverloadableOperatorType.Subtract:
680
 
                                        return "op_Subtraction";
681
 
                                case OverloadableOperatorType.UnaryMinus:
682
 
                                        return "op_UnaryNegation";
683
 
                                case OverloadableOperatorType.UnaryPlus:
684
 
                                        return "op_UnaryPlus";
685
 
                                default:
686
 
                                        throw new NotSupportedException("opeartor type:" + op);
687
 
                        }
688
 
                }
689
 
        }
690
 
}