public override IExpression VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node) { var o = this.semanticModel.GetSymbolInfo(node); var s = o.Symbol as MethodSymbol; if (s != null) { var m = (MethodDefinition)this.mapper.TranslateMetadata(s); var anonDelParameters = new List <IParameterDefinition>(m.Parameters); this.parameters.Add(m, anonDelParameters); IBlockStatement body; var b = node.Body; if (b is ExpressionSyntax) { var e = this.Visit(b); body = new BlockStatement() { Statements = new List <IStatement>() { new ReturnStatement() { Expression = e, } }, }; } else if (b is BlockSyntax) { var sv = new StatementVisitor(this.host, this.semanticModel, this.mapper, m, this); var b2 = (IBlockStatement)sv.Visit(b); body = b2; } else { throw new InvalidDataException("VisitSimpleLambdaExpression: unknown type of body"); } var anon = new AnonymousDelegate() { Body = body, CallingConvention = s.IsStatic ? CallingConvention.HasThis : CallingConvention.Default, Parameters = anonDelParameters, ReturnType = m.Type, Type = this.mapper.Map(this.semanticModel.GetTypeInfo(node).ConvertedType), }; return(anon); } throw new InvalidDataException("VisitSimpleLambdaExpression couldn't find something to return"); }
public BlockStatement GetMethodBody(IMethodDefinition cciMethod, BaseMethodDeclarationSyntax roslynMethod, bool extractContracts) { Contract.Requires(roslynMethod.Body != null); var expressionVisitor = new ExpressionVisitor(this.host, this.semanticModel, this.mapper, cciMethod); var sv = new StatementVisitor(this.host, this.semanticModel, this.mapper, cciMethod, expressionVisitor); var block = roslynMethod.Body; var statements = new List <IStatement>(); if (roslynMethod.Kind == SyntaxKind.ConstructorDeclaration) { var roslynCtor = roslynMethod as ConstructorDeclarationSyntax; var es = new List <IExpression>(); var ps = new List <IParameterTypeInformation>(); ITypeReference ctorClass = null; if (roslynCtor.Initializer != null) { switch (roslynCtor.Initializer.ThisOrBaseKeyword.Kind) { case SyntaxKind.BaseKeyword: ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one? break; case SyntaxKind.ThisKeyword: ctorClass = cciMethod.ContainingType; break; default: var msg = String.Format("Was unable to convert {0} which was used for a base/this ctor call in {1}", roslynCtor.Initializer.ThisOrBaseKeyword, MemberHelper.GetMethodSignature(cciMethod)); throw new ConverterException(msg); } foreach (var a in roslynCtor.Initializer.ArgumentList.Arguments) { var e = expressionVisitor.Visit(a); es.Add(e); } } else { // Create a call to the nullary base constructor ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one? } var thisRef = new ThisReference() { Type = cciMethod.ContainingType, }; var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = ctorClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Parameters = ps, Type = this.host.PlatformType.SystemVoid, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = ctorRef, IsStaticCall = false, ThisArgument = thisRef, Type = this.host.PlatformType.SystemVoid, Arguments = es, } } ); } statements.Add( new EmptyStatement() { Locations = Helper.SourceLocation(this.semanticModel.SyntaxTree, block.OpenBraceToken), } ); foreach (var s in block.Statements) { var s_prime = sv.Visit(s); statements.Add(s_prime); } // REVIEW: need to do this only if debugging info is needed? // (But if it isn't done, then there can be unreachable nops // corresponding to close curlys for blocks because of return // statements within the block. When that happens at the method // level, then peverify is unhappy with the assembly.) //if (false) { // // commented this out because it is needed only if this is being used // // to generate IL that in the end should pass peverify (and run). // statements = CreateUnifiedReturnPoint(statements, cciMethod.Type); //} BlockStatement bs = new BlockStatement() { Statements = statements, }; return(bs); }