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; }
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; } } }
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; }
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); }
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); }