Пример #1
0
 public virtual Expression VisitTemplateInstance(TemplateInstance templateInstance)
 {
     if (templateInstance == null) return null;
     templateInstance.Expression = this.VisitExpression(templateInstance.Expression);
     templateInstance.TypeArguments = this.VisitTypeReferenceList(templateInstance.TypeArguments);
     return templateInstance;
 }
Пример #2
0
 private Expression ParseIndexerCallOrSelector(Expression expression, TokenSet followers){
   TokenSet followersOrContinuers = followers|Token.LeftBracket|Token.LeftParenthesis|Token.Dot;
   for(;;){
     switch (this.currentToken){
       case Token.LeftBracket:
         SourceContext lbCtx = this.scanner.CurrentSourceContext;
         this.GetNextToken();
         if (this.insideModifiesClause && this.currentToken == Token.Multiply){
           // Handle code such as
           //
           //     modifies myArray[*];
           //
           // which means that the method may modify all elements of myArray.
           int savedStartPos = this.scanner.startPos;
           int savedEndPos = this.scanner.endPos;
           this.GetNextToken();
           if (this.currentToken == Token.RightBracket){
             SourceContext sctxt = this.scanner.CurrentSourceContext;
             sctxt.StartPos = lbCtx.StartPos;
             this.GetNextToken();
             return new ModifiesArrayClause(expression, sctxt);
           }
           this.scanner.startPos = savedStartPos;
           this.scanner.endPos = savedEndPos;
         }
         int endCol;
         ExpressionList indices = this.ParseIndexList(followersOrContinuers, lbCtx, out endCol);
         Indexer indexer = new Indexer(expression, indices);
         indexer.SourceContext = expression.SourceContext;
         indexer.SourceContext.EndPos = endCol;
         indexer.ArgumentListIsIncomplete = this.scanner.GetChar(endCol-1) != ']';
         expression = indexer;
         break;
       case Token.LessThan:
         SourceContext ltCtx = this.scanner.CurrentSourceContext;
         ScannerState ss = this.scanner.state;
         int arity;
         TypeNodeList typeArguments = this.ParseTypeArguments(true, false, followers|Token.LeftParenthesis, out endCol, out arity);
         if (typeArguments == null || (typeArguments.Count > 1 && Parser.TypeArgumentListNonFollower[this.currentToken])) {
           this.scanner.endPos = ltCtx.StartPos;
           this.scanner.state = ss;
           this.currentToken = Token.None;
           this.GetNextToken();
           return expression;
         }
         TemplateInstance instance = new TemplateInstance(expression, typeArguments);
         instance.TypeArgumentExpressions = typeArguments == null ? null : typeArguments.Clone();
         instance.SourceContext = expression.SourceContext;
         instance.SourceContext.EndPos = endCol;
         expression = instance;
         break;
       case Token.LeftParenthesis:
         SourceContext lpCtx = this.scanner.CurrentSourceContext;
         this.GetNextToken();
         ExpressionList arguments = this.ParseArgumentList(followersOrContinuers, lpCtx, out endCol);
         if (expression == null) return null;
         if (expression is Identifier && arguments.Count == 1 && ((Identifier)expression).Name == "old" && InEnsuresContext){
           OldExpression old = new OldExpression(arguments[0]);
           typeArguments = null;
           old.SourceContext = expression.SourceContext;
           old.SourceContext.EndPos = endCol;
           expression = old;
           break;
         }
         if (expression is TemplateInstance)
           ((TemplateInstance)expression).IsMethodTemplate = true;
         MethodCall mcall = new MethodCall(expression, arguments);
         typeArguments = null;
         mcall.GiveErrorIfSpecialNameMethod = true;
         mcall.SourceContext = expression.SourceContext;
         mcall.SourceContext.EndPos = endCol;
         mcall.ArgumentListIsIncomplete = this.scanner.GetChar(endCol-1) != ')';
         expression = mcall;
         break;
       case Token.LeftBrace:
         if (this.compatibilityOn || this.scanner.TokenIsFirstAfterLineBreak) goto default;
         Expression quant = this.ParseComprehension(followers);
         if (quant == null) { break; }
         Block argBlock = new Block(new StatementList(new ExpressionStatement(quant)),quant.SourceContext,
           this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode);
         argBlock.IsUnsafe = this.inUnsafeCode;
         argBlock.SourceContext = quant.SourceContext;
         ExpressionList arguments2 = new ExpressionList(new AnonymousNestedFunction(new ParameterList(0), argBlock, quant.SourceContext));
         MethodCall mcall2 = new MethodCall(expression, arguments2);
         typeArguments = null;
         mcall2.GiveErrorIfSpecialNameMethod = true;
         mcall2.SourceContext = expression.SourceContext;
         mcall2.SourceContext.EndPos = this.scanner.endPos;
         expression = mcall2;
         break;
       case Token.Dot:
         expression = this.ParseQualifiedIdentifier(expression, followersOrContinuers);
         break;
       case Token.RealLiteral:
         string tokStr = this.scanner.GetTokenSource();
         if (this.insideModifiesClause && tokStr == ".0") {
           // this case is here only for parsing ".0" while parsing a modifies clause
           // e.g., "modifies this.0;"
           this.GetNextToken(); // eat the ".0"
           return new ModifiesNothingClause(expression, this.scanner.CurrentSourceContext);
         } else {
           return expression;
         }
       case Token.Arrow:
         if (!this.allowUnsafeCode){
           this.HandleError(Error.IllegalUnsafe);
           this.allowUnsafeCode = true;
         }
         this.currentToken = Token.Dot;
         AddressDereference ad = new AddressDereference();
         ad.Address = expression;
         ad.ExplicitOperator = AddressDereference.ExplicitOp.Arrow;
         ad.SourceContext = expression.SourceContext;
         expression = this.ParseQualifiedIdentifier(ad, followersOrContinuers);
         break;
       default:
         return expression;
     }
   }
 }
Пример #3
0
 private InterfaceList ParseInterfaceList(TokenSet followers, bool expectLeftBrace){
   InterfaceList ilist = new InterfaceList();
   TokenSet followersOrComma = followers|Token.Comma;
   for(;;){
     Expression id = this.scanner.GetIdentifier();
     switch(this.currentToken){
       case Token.Bool:
       case Token.Decimal:
       case Token.Sbyte:
       case Token.Byte:
       case Token.Short:
       case Token.Ushort:
       case Token.Int:
       case Token.Uint:
       case Token.Long:
       case Token.Ulong:
       case Token.Char:
       case Token.Float:
       case Token.Double:
       case Token.Object:
       case Token.String:
       case Token.Void:
         TypeExpression texpr = this.TypeExpressionFor(this.currentToken);
         this.GetNextToken();
         ilist.Add(new InterfaceExpression(texpr.Expression, texpr.SourceContext));
         goto lookForComma;
       default:
         bool idOK = Parser.IdentifierOrNonReservedKeyword[this.currentToken];
         if (idOK){
           this.GetNextToken();
           if (this.currentToken == Token.DoubleColon){
             this.GetNextToken();
             Identifier id2 = this.scanner.GetIdentifier();
             id2.Prefix = (Identifier)id;
             id2.SourceContext.StartPos = id.SourceContext.StartPos;
             this.SkipIdentifierOrNonReservedKeyword();
             id = id2;
           }
           if (this.currentToken == Token.Dot)
             id = this.ParseQualifiedIdentifier(id, followersOrComma|Token.LessThan);
         }else{
           int col = this.scanner.endPos;
           this.SkipIdentifierOrNonReservedKeyword(Error.TypeExpected);
           if (col == this.scanner.endPos && this.currentToken != Token.EndOfFile){
             //Did not consume a token, but just gave an error
             if (!followersOrComma[this.currentToken]) this.GetNextToken();
             if (followers[this.currentToken]) return ilist;
             if (this.currentToken != Token.Comma){
               if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) continue;
               break;
             }
             this.GetNextToken();
             continue;
           }
           if (this.currentToken == Token.Dot)
             id = this.ParseQualifiedIdentifier(id, followersOrComma|Token.LessThan);
           if (!idOK) goto lookForComma;
         }
         break;
     }
     //I really want an Identifier here for StartName
     if (this.sink != null) {
       Identifier name = id as Identifier;
       if (id is QualifiedIdentifier) {
         name = ((QualifiedIdentifier)id).Identifier;
       }
       if (name != null) {
         this.sink.StartName(name);
       }
     }
     InterfaceExpression ifaceExpr = new InterfaceExpression(id, id.SourceContext);
     if (this.currentToken == Token.LessThan){
     yetAnotherTypeArgumentList:
       this.GetNextToken();
       TypeNodeList arguments = new TypeNodeList();
       for(;;){
         TypeNode t = this.ParseTypeExpression(null, followers|Token.Comma|Token.GreaterThan);
         arguments.Add(t);
         if (this.currentToken != Token.Comma) break;
         this.GetNextToken();
       }
       ifaceExpr.TemplateArguments = arguments;
       ifaceExpr.TemplateArgumentExpressions = arguments.Clone();
       ifaceExpr.SourceContext.EndPos = this.scanner.endPos;
       this.Skip(Token.GreaterThan);
       if (this.currentToken == Token.Dot) {
         TemplateInstance tempInst = new TemplateInstance(ifaceExpr.Expression, ifaceExpr.TemplateArguments);
         tempInst.TypeArgumentExpressions = ifaceExpr.TemplateArguments == null ? null : ifaceExpr.TemplateArguments.Clone();
         tempInst.SourceContext = ifaceExpr.SourceContext;
         ifaceExpr.Expression = this.ParseQualifiedIdentifier(tempInst, followersOrComma|Token.LessThan);
         ifaceExpr.TemplateArguments = null;
         ifaceExpr.TemplateArgumentExpressions = null;
         if (ifaceExpr.Expression != null) ifaceExpr.SourceContext = ifaceExpr.Expression.SourceContext;
         if (this.currentToken == Token.LessThan) goto yetAnotherTypeArgumentList;
       }
     }
     ilist.Add(ifaceExpr);
   lookForComma:
     if (Parser.TypeOperator[this.currentToken] && !(expectLeftBrace && this.currentToken == Token.LeftBrace)){
       this.HandleError(Error.BadBaseType);
       this.GetNextToken();
       if (this.currentToken == Token.RightBracket || this.currentToken == Token.RightBrace)
         this.GetNextToken();
       this.SkipTo(followersOrComma, Error.None);
     }else if (!followersOrComma[this.currentToken])
       this.SkipTo(followersOrComma, Error.TypeExpected);
     if (this.currentToken == Token.Comma){
       if (followers[Token.Comma] && followers[Token.GreaterThan])
         break; //Parsing the constraint of a type parameter
       this.GetNextToken();
       if (expectLeftBrace && (this.currentToken == Token.Class || this.currentToken == Token.Struct || this.currentToken == Token.New))
         break;
     }else if (!Parser.TypeStart[this.currentToken] || this.currentToken == Token.Where)
       break;
     else if (Parser.ContractStart[this.currentToken])
       break;
   }
   return ilist;
 }
Пример #4
0
 private Expression ParseNamespaceOrTypeName(Expression root, bool allowDoubleColon, TokenSet followers){
   if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken]){
     if (this.currentToken == Token.EndOfFile){
       root = new QualifiedIdentifier(root, this.scanner.GetIdentifier(), root.SourceContext);
       root.SourceContext.EndPos = this.scanner.endPos;
     }
     this.SkipTo(followers, Error.ExpectedIdentifier);
     return root;
   }
   Identifier id = this.scanner.GetIdentifier();
   if (root == Identifier.Empty){
     root = id;
   }else{
     root = new QualifiedIdentifier(root, id, root.SourceContext);
     root.SourceContext.EndPos = id.SourceContext.EndPos;
   }
   this.GetNextToken();
 tryAgain:
   if (this.currentToken != Token.Dot){
     if (this.currentToken == Token.DoubleColon && allowDoubleColon){
       Debug.Assert(root == id);
       this.GetNextToken();
       Identifier ident = this.scanner.GetIdentifier();
       this.SkipIdentifierOrNonReservedKeyword();
       ident.Prefix = id;
       ident.SourceContext.StartPos = id.SourceContext.StartPos;
       root = ident;
       allowDoubleColon = false;
       goto tryAgain;
     }
     TemplateInstance result = null;
     while (this.currentToken == Token.LessThan) {
       int endCol, arity;
       if (result == null) {
         result = new TemplateInstance();
         result.Expression = root;
         result.SourceContext = root.SourceContext;
       }
       result.TypeArgumentExpressions = this.ParseTypeArguments(false, false, followers|Token.Dot, out endCol, out arity);
       result.TypeArguments = result.TypeArgumentExpressions == null ? null : result.TypeArgumentExpressions.Clone();
       result.SourceContext.EndPos = endCol;
       if (result.TypeArguments == null) {
         result.TypeArguments = new TypeNodeList(1);
         result.TypeArguments.Add(null);
       }
       if (this.currentToken == Token.Dot) {
         root = this.ParseQualifiedIdentifier(result, followers|Token.LessThan, false);
         result = null;
       }
     }
     if (result != null) root = result;
     this.SkipTo(followers);
     return root;
   }
   this.GetNextToken();
   return this.ParseNamespaceOrTypeName(root, false, followers);
 }
Пример #5
0
 public EventingVisitor(Action<TemplateInstance> visitTemplateInstance) { VisitedTemplateInstance += visitTemplateInstance; } public event Action<TemplateInstance> VisitedTemplateInstance; public override Expression VisitTemplateInstance(TemplateInstance templateInstance) { if (VisitedTemplateInstance != null) VisitedTemplateInstance(templateInstance); return base.VisitTemplateInstance(templateInstance); }