This project is read-only.

anonymous delegates

Jul 8, 2011 at 10:12 AM



I'm trying to generate a piece of code, but I can't make it work somehow. I have an object, which has a property of the type Action(no generic). I want to set the property, but run into problems. This is what I tried:

//Setup a BlockStatement with only 1 statement: call a method.
List<Statement> anStmts = new List<Statement>();
QualifiedName qnExecCall = new QualifiedName(new ThisReference(null), GetSimpleNameFor(execMethod.Name.Value), null);
anStmts.Add(new ExpressionStatement(new MethodCall(qnExecCall, new List<Expression>(), null)));
BlockStatement anBlock = new BlockStatement(anStmts, null);

//Create an AnonymousMethod with the BlockStatement
AnonymousMethod anMethod = new AnonymousMethod(new List<ParameterDeclaration>(), anBlock, null);

//the delegate
AnonymousDelegate anDel = new AnonymousDelegate(anMethod, null);

//Assign the delegate to the property ExecuteDelegate of the backing field object
QualifiedName qn = new QualifiedName(GetSimpleNameFor(backingName.Value), GetSimpleNameFor("ExecuteDelegate"), null);
Assignment assignExec = new Assignment(new TargetExpression(qn), anDel, null);
stmtsAssign.Add(new ExpressionStatement(assignExec));

When it runs, I receive the following error: Unhandled Exception: System.Diagnostics.Contracts.ContractException: Assumption failed.: IAnonymousDelegate nodes must be replaced before trying to convert the Code Model to IL.


What am I doing wrong?

Or are anonymous delegates not supported yet in the AST ?






Jul 9, 2011 at 1:15 AM

The error is quite specific and should only show up if you are trying to convert the CodeModel resulting from your AST into IL without first "normalizing" it to get rid of iterators and anonymous delegates. If your code is part of an AST.MethodBody, then normalization should happen before the conversion to IL. In other words this code should run:

     private void GenerateIL()
      //^ ensures this.privateHelperTypes != null;
      this.ilWasGenerated = true;
      if (this.block == null) {
        this.localVariables = Enumerable<ILocalDefinition>.Empty;
        this.maxStack = 0;
        this.operations = Enumerable<IOperation>.Empty;
        this.operationExceptionInformation = Enumerable<IOperationExceptionInformation>.Empty;
        this.localVariables = Enumerable<ILocalDefinition>.Empty;
        this.privateHelperTypes = Enumerable<ITypeDefinition>.Empty;

      MethodBodyNormalizer normalizer = new MethodBodyNormalizer(this.Block.Compilation.HostEnvironment,
      ISourceMethodBody normalizedBody = normalizer.GetNormalizedSourceMethodBodyFor(this.MethodDefinition, this.Block);
      this.isIteratorBody = normalizer.IsIteratorBody;

      CodeModelToILConverter converter = new CodeModelToILConverter(this.Block.Compilation.HostEnvironment,

      this.localScopes = converter.GetLocalScopes();
      this.localVariables = converter.GetLocalVariables();
      this.maxStack = converter.MaximumStackSizeNeeded;
      this.operations = converter.GetOperations();
      this.operationExceptionInformation = converter.GetOperationExceptionInformation();
      this.privateHelperTypes = normalizedBody.PrivateHelperTypes;

Possibly, this is a problem in your code. If you cannot get to the bottom of this, please see if you can reproduce the problem with a small sample (preferably based on HelloAST) and create an issue for it.