Example #1
0
 private Expression ParseNew(TokenSet followers){
   SourceContext ctx = this.scanner.CurrentSourceContext;
   Debug.Assert(this.currentToken == Token.New);
   this.GetNextToken();
   TypeNode allocator = null;
   if (this.currentToken == Token.LeftBracket) {
     this.GetNextToken();
     if (this.currentToken == Token.RightBracket) {
       return this.ParseNewImplicitlyTypedArray(ctx, followers);
     }
     // parse [Delayed] annotation (or allocator)
     allocator = this.ParseBaseTypeExpression(null, followers|Token.RightBracket, false, false);
     if (allocator == null){this.SkipTo(followers, Error.None); return null;}
     this.Skip(Token.RightBracket);
   }
   if (this.currentToken == Token.LeftBrace)
     return this.ParseNewAnonymousTypeInstance(ctx, followers);
   Expression owner = null;
   // Allow owner argument for each constructor: "new <ow> ..."
   if (this.currentToken == Token.LessThan) {
     this.GetNextToken();
     owner = this.ParsePrimaryExpression(followers | Token.GreaterThan);
     if (this.currentToken == Token.GreaterThan)
       this.GetNextToken();
   }
   // Make it explicit that the base type stops at "!", which is handled by
   // the code below.
   TypeNode t = this.ParseBaseTypeExpression(null, followers|Parser.InfixOperators|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis|Token.LogicalNot, false, false);
   if (t == null){this.SkipTo(followers, Error.None); return null;}
   if (this.currentToken == Token.Conditional) {
     TypeNode type = t;
     t = new NullableTypeExpression(type);
     t.SourceContext = type.SourceContext;
     t.SourceContext.EndPos = this.scanner.endPos;
     this.GetNextToken();
   }else if (this.currentToken == Token.LogicalNot){
     TypeNode type = t;
     t = new NonNullableTypeExpression(type);
     t.SourceContext = type.SourceContext;
     t.SourceContext.EndPos = this.scanner.endPos;
     this.GetNextToken();
   }else if (this.currentToken == Token.Multiply){
     this.GetNextToken();
     t = new PointerTypeExpression(t, t.SourceContext);
     t.SourceContext.EndPos = this.scanner.endPos;
     if (!this.inUnsafeCode)
       this.HandleError(t.SourceContext, Error.UnsafeNeeded);
   }
   ctx.EndPos = t.SourceContext.EndPos;
   // special hack [Delayed] in custom allocator position is used to mark the array as
   // a delayed construction. This annotation is used in the Definite Assignment analysis.
   //
   TypeExpression allocatorExp = allocator as TypeExpression;
   if (allocatorExp != null) {
     Identifier allocId = allocatorExp.Expression as Identifier;
     if (allocId != null && allocId.Name == "Delayed") {
       t = new RequiredModifierTypeExpression(t, TypeExpressionFor("Microsoft","Contracts","DelayedAttribute"));
       allocator = null; // not really a custom allocation
     }
   }
   int rank = this.ParseRankSpecifier(false, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
   SourceContext lbCtx = ctx;
   while (rank > 0 && this.currentToken == Token.LeftBracket){
     lbCtx = this.scanner.CurrentSourceContext;
     t = new ArrayTypeExpression(t, rank);
     rank = this.ParseRankSpecifier(false, followers|Token.LeftBrace|Token.LeftBracket);
   }
   if (rank > 0){
     //new T[] {...} or new T[,] {{..} {...}...}, etc where T can also be an array type
     ConstructArray consArr = new ConstructArray();
     consArr.SourceContext = ctx;
     consArr.ElementType = consArr.ElementTypeExpression = t;
     consArr.Rank = rank;
     if (this.currentToken == Token.LeftBrace)
       consArr.Initializers = this.ParseArrayInitializer(rank, t, followers);
     else{
       if (Parser.UnaryStart[this.currentToken])
         this.HandleError(Error.ExpectedLeftBrace);
       else
         this.HandleError(Error.MissingArraySize);
       while (Parser.UnaryStart[this.currentToken]){
         this.ParseExpression(followers|Token.Comma|Token.RightBrace);
         if (this.currentToken != Token.Comma) break;
         this.GetNextToken();
       }
       if (this.currentToken == Token.RightBrace) this.GetNextToken();
       this.SkipTo(followers);
     }
     if (owner != null) {
       consArr.Owner = owner;
     }
     return consArr;
   }
   if (rank < 0){
     //new T[x] or new T[x,y] etc. possibly followed by an initializer or element type rank specifier
     ConstructArray consArr = new ConstructArray();
     consArr.SourceContext = ctx;
     consArr.Operands = this.ParseIndexList(followers|Token.LeftBrace|Token.LeftBracket, lbCtx, out consArr.SourceContext.EndPos);
     rank = consArr.Operands.Count;
     if (this.currentToken == Token.LeftBrace)
       consArr.Initializers = this.ParseArrayInitializer(rank, t, followers);
     else{
       int elementRank = this.ParseRankSpecifier(true, followers);
     tryAgain:
       if (elementRank > 0) t = this.ParseArrayType(elementRank, t, followers);
       if (this.currentToken == Token.LeftBrace)
         consArr.Initializers = this.ParseArrayInitializer(rank, t, followers);
       else{
         if (this.currentToken == Token.LeftBracket){ //new T[x][y] or something like that
           lbCtx = this.scanner.CurrentSourceContext;
           this.GetNextToken();
           SourceContext sctx = this.scanner.CurrentSourceContext;
           this.ParseIndexList(followers, lbCtx, out sctx.EndPos);
           this.HandleError(sctx, Error.InvalidArray);
           elementRank = 1;
           goto tryAgain;
         }else
           this.SkipTo(followers);
       }
     }
     consArr.ElementType = consArr.ElementTypeExpression = t;
     consArr.Rank = rank;
     if (owner != null) {
       consArr.Owner = owner;
     }
     return consArr;
   }
   ExpressionList arguments = null;
   SourceContext lpCtx = this.scanner.CurrentSourceContext;
   bool sawLeftParenthesis = false;
   if (this.currentToken == Token.LeftParenthesis){
     if (rank == 0 && t is NonNullableTypeExpression) {
       this.SkipTo(followers, Error.BadNewExpr);
       return null;
     }
     sawLeftParenthesis = true;
     this.GetNextToken();
     arguments = this.ParseArgumentList(followers, lpCtx, out ctx.EndPos);
   }else if (this.currentToken == Token.LeftBrace){
     Expression quant = this.ParseComprehension(followers);
     arguments = new ExpressionList(quant);
   }else{
     this.SkipTo(followers, Error.BadNewExpr);
     Construct c = new Construct();
     if (t is TypeExpression)
       c.Constructor = new MemberBinding(null, t, t.SourceContext);
     c.SourceContext = ctx;
     return c;
   }
   if (sawLeftParenthesis && this.currentToken == Token.LeftBrace){
   }
   Construct cons = new Construct(new MemberBinding(null, t), arguments);
   cons.SourceContext = ctx;
   if (owner != null)
     cons.Owner = owner;
   return cons;
 }
Example #2
0
 private TypeNode ParseArrayType(int rank, TypeNode elementType, TokenSet followers){
   SourceContext sctx = elementType.SourceContext;
   Int32List rankList = new Int32List();
   do{
     rankList.Add(rank);
     rank = this.ParseRankSpecifier(false, followers);
   }while (rank > 0);
   for (int i = rankList.Count; i > 0; i--)
     elementType = new ArrayTypeExpression(elementType, rankList[i-1]);
   elementType.SourceContext = sctx;
   return elementType;
 }