Inheritance: Microsoft.Cci.MutableCodeModel.Expression, IBoundExpression
    /// <summary>
    /// If a definition should be captured, capture it. Otherwise noop. 
    /// 
    /// The act of capturing means mapping the definition (or its type's interned id if the definition is a reference to THIS) to
    /// a new BoundField object that represents a field in the closure class. 
    /// </summary>
    /// <param name="definition"></param>
    private void CaptureDefinition(object definition) {
      IThisReference/*?*/ thisRef = definition as IThisReference;
      if (thisRef != null) {
        definition = thisRef.Type.ResolvedType.InternedKey;
      }
      if (this.fieldForCapturedLocalOrParameter.ContainsKey(definition)) return;

      IName/*?*/ name = null;
      ITypeReference/*?*/ type = null;
      ILocalDefinition/*?*/ local = definition as ILocalDefinition;
      var containingClass = this.generatedclosureClass;
      if (local != null) {
        if (!this.localOrParameter2ClosureClass.TryGetValue(local, out containingClass)) return;
        if (false && containingClass == this.generatedclosureClass) {
          // A use of a local is captured only if it is found in a *nested* closure,
          // not the closure where the local is defined.
          return;
        }
        name = local.Name;
        type = local.Type;
      } else {
        IParameterDefinition/*?*/ par = definition as IParameterDefinition;
        if (par != null) {
          if (!this.localOrParameter2ClosureClass.TryGetValue(par, out containingClass)) return;
          name = par.Name;
          type = par.Type;
        } else {
          if (definition is uint) {
            type = thisRef.Type;
            name = this.nameTable.GetNameFor("__this value");
          } else return;
        }
      }
      if (name == null) return;

      FieldDefinition field = new FieldDefinition() {
        ContainingTypeDefinition = containingClass,
        InternFactory = this.host.InternFactory,
        Name = name,
        Type = this.copyTypeToClosure.Visit(type),
        Visibility = TypeMemberVisibility.Public
      };
      containingClass.Fields.Add(field);
      BoundField be = new BoundField(field, field.Type);
      this.fieldForCapturedLocalOrParameter.Add(definition, be);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Create fields for the closure class, which include fields for captured variables and fields for maintaining the state machine.
    /// </summary>
    private void CreateIteratorClosureFields(IteratorClosureInformation iteratorClosure)
      //^ requires (iteratorClosure.ElementType != null);
    {
      // Create fields of the closure class: parameters and this
      if (!this.method.IsStatic) {
        FieldDefinition field = new FieldDefinition();
        // TODO: naming convention should use csc's.
        field.InternFactory = this.host.InternFactory;
        field.Name = this.host.NameTable.GetNameFor("<>__" + "this");
        //ITypeReference typeRef;
        //if (TypeHelper.TryGetFullyInstantiatedSpecializedTypeReference(method.ContainingTypeDefinition, out typeRef))
        //  field.Type = typeRef;
        //else
        //  field.Type = method.ContainingTypeDefinition;
        field.Type = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)method.ContainingTypeDefinition, this.host.InternFactory);
        field.Visibility = TypeMemberVisibility.Public;
        field.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
        iteratorClosure.ThisField = field;
        BoundField boundField = new BoundField(field, iteratorClosure.ThisFieldReference.Type);
        this.FieldForCapturedLocalOrParameter.Add(new ThisReference(), boundField);
      }
      foreach (IParameterDefinition parameter in this.method.Parameters) {
        FieldDefinition field = new FieldDefinition();
        field.InternFactory = this.host.InternFactory;
        field.Name = parameter.Name;
        field.Type = this.copyTypeToClosure.Visit(parameter.Type);
        field.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
        field.Visibility = TypeMemberVisibility.Public;
        iteratorClosure.AddField(field);
        BoundField boundField = new BoundField(field, field.Type);
        this.FieldForCapturedLocalOrParameter.Add(parameter, boundField);
      }
      // Create fields of the closure class: Locals
      foreach (ILocalDefinition local in this.allLocals) {
        FieldDefinition field = new FieldDefinition();
        field.InternFactory = this.host.InternFactory;
        field.Name = this.host.NameTable.GetNameFor("<>__" + local.Name.Value + this.privateHelperTypes.Count);
        field.Type = this.copyTypeToClosure.Visit(local.Type);
        field.Visibility = TypeMemberVisibility.Public;
        field.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
        iteratorClosure.AddField(field);
        BoundField boundField = new BoundField(field, field.Type);
        this.FieldForCapturedLocalOrParameter.Add(local, boundField);
      }
      // Create fields: current, state, and l_initialThreadId
      FieldDefinition current = new FieldDefinition();
      current.InternFactory = this.host.InternFactory;
      current.Name = this.host.NameTable.GetNameFor("<>__" + "current");
      current.Type = iteratorClosure.ElementType;
      current.Visibility = TypeMemberVisibility.Private;
      current.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      iteratorClosure.CurrentField = current;

      FieldDefinition state = new FieldDefinition();
      state.InternFactory = this.host.InternFactory;
      state.Name = this.host.NameTable.GetNameFor("<>__" + "state");
      state.Type = this.host.PlatformType.SystemInt32;
      state.Visibility = TypeMemberVisibility.Private;
      state.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      iteratorClosure.StateField = state;

      FieldDefinition initialThreadId = new FieldDefinition();
      initialThreadId.InternFactory = this.host.InternFactory;
      initialThreadId.Name = this.host.NameTable.GetNameFor("<>__" + "l_initialThreadId");
      initialThreadId.Type = this.host.PlatformType.SystemInt32;
      initialThreadId.Visibility = TypeMemberVisibility.Private;
      initialThreadId.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      iteratorClosure.InitialThreadId = initialThreadId;
    }