示例#1
0
文件: Rewriter.cs 项目: xornand/cci
    private NamespaceTypeDefinition CreateContractReferenceAssemblyAttribute(IRootUnitNamespace rootNs) {

      var internFactory = this.host.InternFactory;
      var nameTable = this.host.NameTable;

      var contractReferenceAssemblyAttributeName = nameTable.GetNameFor("ContractReferenceAssemblyAttribute");
      var contractNamespaceName = nameTable.GetNameFor("System.Diagnostics.Contracts");

      #region Define type
      CustomAttribute compilerGeneratedAttribute = new CustomAttribute() {
        Constructor = new Microsoft.Cci.MethodReference(
          this.host,
          this.compilerGeneratedAttributeType,
          CallingConvention.HasThis,
          this.systemVoidType,
          this.host.NameTable.Ctor,
          0)
      };

      var contractsNs = new NestedUnitNamespace() {
        ContainingUnitNamespace = rootNs,
        Name = contractNamespaceName,
      };
      NamespaceTypeDefinition result = new NamespaceTypeDefinition() {
        Name = contractReferenceAssemblyAttributeName,
        Attributes = new List<ICustomAttribute>{ compilerGeneratedAttribute },
        BaseClasses = new List<ITypeReference>{ this.systemAttributeType },
        ContainingUnitNamespace = contractsNs, //unitNamespace,
        InternFactory = internFactory,
        IsBeforeFieldInit = true,
        IsClass = true,
        IsSealed = true,
        Methods = new List<IMethodDefinition>(),
        Layout = LayoutKind.Auto,
        StringFormat = StringFormatKind.Ansi,
      };
      contractsNs.Members.Add(result);
      this.allTypes.Add(result);
      #endregion Define type
      #region Define the ctor
      List<IStatement> statements = new List<IStatement>();
      SourceMethodBody body = new SourceMethodBody(this.host) {
        LocalsAreZeroed = true,
        Block = new BlockStatement() { Statements = statements },
      };
      MethodDefinition ctor = new MethodDefinition() {
        Body = body,
        CallingConvention = CallingConvention.HasThis,
        ContainingTypeDefinition = result,
        InternFactory = internFactory,
        IsRuntimeSpecial = true,
        IsStatic = false,
        IsSpecialName = true,
        Name = nameTable.Ctor,
        Type = this.systemVoidType,
        Visibility = TypeMemberVisibility.Public,
      };
      body.MethodDefinition = ctor;
      var thisRef = new ThisReference() { Type = result, };
      // base();
      foreach (var baseClass in result.BaseClasses) {
        var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
          CallingConvention = CallingConvention.HasThis,
          ContainingType = baseClass,
          GenericParameterCount = 0,
          InternFactory = this.host.InternFactory,
          Name = nameTable.Ctor,
          Type = this.systemVoidType,
        };
        statements.Add(
          new ExpressionStatement() {
            Expression = new MethodCall() {
              MethodToCall = baseCtor,
              IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
              ThisArgument = new ThisReference() { Type = result, },
              Type = this.systemVoidType, // REVIEW: Is this the right way to do this?
              Arguments = new List<IExpression>(),
            }
          }
          );
        break;
      }

      // return;
      statements.Add(new ReturnStatement());
      result.Methods.Add(ctor);
      #endregion Define the ctor
      return result;
    }
 /// <summary>
 /// Returns an expression that results in a closure object instance that contains the given field.
 /// If the expression will be evaluated in the body of this.method, the result is a bound expression
 /// that references the local that contains the object. Otherwise it is the "this" argument of the 
 /// anonymous delegate method, possibly with a number of field accesses to chase down the outer closure chain.
 /// </summary>
 /// <param name="closureField">A reference to a field from the "self instance" of a closure class.</param>
 private IExpression GetClosureObjectInstanceContaining(IFieldReference closureField) {
   if (this.isInsideAnonymousMethod) {
     IExpression result = new ThisReference() { Type = this.currentClosureSelfInstance };
     while (result.Type != closureField.ContainingType) {
       var outerClosureField = this.fieldReferencesForUseInsideAnonymousMethods[result.Type];
       result = new BoundExpression() { Instance = result, Definition = outerClosureField, Type = outerClosureField.Type };
     }
     return result;
   } else {
     foreach (var instance in this.closureLocalInstances) {
       if (instance.Type == closureField.ContainingType) return instance;
     }
     return this.currentClosureObject;
   }
 }
示例#3
0
 /// <summary>
 /// Visits the specified this reference.
 /// </summary>
 /// <param name="thisReference">The this reference.</param>
 public override void Visit(IThisReference thisReference)
 {
     ThisReference mutableThisReference = new ThisReference(thisReference);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableThisReference);
 }
    /// <summary>
    /// Returns a method whose body is empty, but which can be replaced with the real body when it is
    /// available.
    /// </summary>
    /// <remarks>
    /// Public because it needs to get called when an anonymous delegate is encountered
    /// while translating a method body. Just mapping the anonymous delegate doesn't
    /// provide the information needed. The parameters of a method reference are not
    /// IParameterDefinitions.
    /// </remarks>
    public MethodDefinition TranslateMetadata(R.IMethodSymbol methodSymbol) {
      Contract.Requires(methodSymbol != null);
      Contract.Ensures(Contract.Result<MethodDefinition>() != null);

      var containingType = (ITypeDefinition)this.typeSymbolCache[methodSymbol.ContainingType];
      var isConstructor = methodSymbol.MethodKind == R.CommonMethodKind.Constructor;
      List<IParameterDefinition> parameters = new List<IParameterDefinition>();

      var m = new MethodDefinition() {
        CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis,
        ContainingTypeDefinition = containingType,
        InternFactory = this.host.InternFactory,
        IsHiddenBySignature = true, // REVIEW
        IsNewSlot = containingType.IsInterface, // REVIEW
        IsRuntimeSpecial = isConstructor,
        IsSpecialName = isConstructor,
        IsStatic = methodSymbol.IsStatic,
        IsVirtual = containingType.IsInterface, // REVIEW: Why doesn't using methodSymbol.Virtual work for interface methods?
        Locations = Helper.WrapLocations(methodSymbol.Locations),
        Name = this.nameTable.GetNameFor(methodSymbol.Name),
        Parameters = parameters,
        Type = this.Map(methodSymbol.ReturnType),
        Visibility = this.Map(methodSymbol.DeclaredAccessibility),
      };

      // IMPORTANT: Have to add it to the cache before doing anything else because it may
      // get looked up if it is generic and a parameter's type involves the generic
      // method parameter.
      this.methodSymbolCache.Add(methodSymbol, m);

      #region Define the generic parameters
      if (methodSymbol.IsGenericMethod) {
      var genericParameters = new List<IGenericMethodParameter>();
      foreach (var gp in methodSymbol.TypeParameters) {
        var gp2 = this.CreateTypeDefinition(gp);
        genericParameters.Add((IGenericMethodParameter) gp2);
      }
      m.GenericParameters = genericParameters;
      }
      #endregion

      #region Define the parameters
      ushort i = 0;
      foreach (var p in methodSymbol.Parameters) {
        var p_prime = new ParameterDefinition() {
          ContainingSignature = m,
          IsByReference = p.RefKind == RefKind.Ref,
          IsIn = p.RefKind == RefKind.None,
          IsOut = p.RefKind == RefKind.Out,
          Name = nameTable.GetNameFor(p.Name),
          Type = this.Map(p.Type),
          Index = i++,
        };
        parameters.Add(p_prime);
      }
      #endregion Define the parameters

      #region Define default ctor, if needed
      if (/*methodSymbol.IsSynthesized &&*/ isConstructor) { // BUGBUG!!
        m.IsHiddenBySignature = true;
        m.IsRuntimeSpecial = true;
        m.IsSpecialName = true;
        var statements = new List<IStatement>();
        var body = new SourceMethodBody(this.host, null, null) {
          LocalsAreZeroed = true,
          Block = new BlockStatement() { Statements = statements },
        };
        var thisRef = new ThisReference() { Type = containingType, };
        // base();
        foreach (var baseClass in containingType.BaseClasses) {
          var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
            CallingConvention = CallingConvention.HasThis,
            ContainingType = baseClass,
            GenericParameterCount = 0,
            InternFactory = this.host.InternFactory,
            Name = nameTable.Ctor,
            Type = this.host.PlatformType.SystemVoid,
          };
          statements.Add(
            new ExpressionStatement() {
              Expression = new MethodCall() {
                MethodToCall = baseCtor,
                IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
                ThisArgument = thisRef,
                Type = this.host.PlatformType.SystemVoid, // REVIEW: Is this the right way to do this?
                Arguments = new List<IExpression>(),
              }
            }
            );
          break;
        }
        // return;
        statements.Add(new ReturnStatement());
        body.MethodDefinition = m;
        m.Body = body;
      }
      #endregion

      return m;

    }
 public static IExpression GenerateExpressionFromString(string strExpr, IMetadataHost host, IMethodDefinition method)
 {
     strExpr = Normalize(strExpr);
     string rpn = GetRPN(strExpr);
     Stack<IExpression> stVals = new Stack<IExpression>();
     RPNEnumerator rpnEnum = new RPNEnumerator(rpn);
     var int32Type = host.PlatformType.SystemInt32;
     var boolType = host.PlatformType.SystemBoolean;
     while (rpnEnum.MoveNext())
     {
         RPNValue rpnVal = (RPNValue)rpnEnum.Current;
         if (rpnVal.type == RPNValueType.OPERAND)
         {
             if (reNum.IsMatch(rpnVal.val))
             {
                 stVals.Push(new CompileTimeConstant() { Type = int32Type, Value = int.Parse(rpnVal.val.Replace(':', '-')) });
             }
             else
             {
                 IExpression expr = null;
                 var exprParts = rpnVal.val.Split('.');
                 if (exprParts[0] == "this")
                 {
                     expr = new ThisReference() { Type = method.ContainingType.ResolvedType };
                 }
                 else
                 {
                     foreach (var arg in method.Parameters)
                     {
                         if (arg.Name.Value == exprParts[0])
                         {
                             expr = new BoundExpression() { Type = arg.Type.ResolvedType, Definition = arg };
                             break;
                         }
                     }
                 }
                 if (expr != null && exprParts.Length > 1)
                 {
                     for (int i = 1; i < exprParts.Length; i++)
                     {
                         expr = GetExprWithAccesor(expr, exprParts[i], host);
                     }
                 }
                 if (expr == null || expr.Type.ResolvedType != int32Type.ResolvedType)
                 {
                     return null;
                 }
                 stVals.Push(expr);
             }
         }
         else
         {
             var v1 = stVals.Pop();
             var v2 = stVals.Pop();
             if      (rpnVal.val == "+") stVals.Push(new Addition() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "-") stVals.Push(new Subtraction() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "*") stVals.Push(new Multiplication() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "/") stVals.Push(new Division() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "=") stVals.Push(new Equality() { Type = int32Type, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "&") stVals.Push(new Conditional() { Type = boolType, Condition = v2, ResultIfTrue = v1, ResultIfFalse = new CompileTimeConstant() { Type = int32Type, Value = 0 } });
             else if (rpnVal.val == "|") stVals.Push(new Conditional() { Type = boolType, Condition = v2, ResultIfTrue = new CompileTimeConstant() { Type = int32Type, Value = 1 }, ResultIfFalse = v1 });
             else if (rpnVal.val == ">") stVals.Push(new GreaterThan() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "<") stVals.Push(new LessThan() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "%") stVals.Push(new GreaterThanOrEqual() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else if (rpnVal.val == "#") stVals.Push(new LessThanOrEqual() { Type = boolType, LeftOperand = v2, RightOperand = v1 });
             else return null;
         }
     }
     if (stVals.Count > 0)
     {
         return stVals.Pop();
     }
     return null;
 }
示例#6
0
 /// <summary>
 /// Visits the specified this reference.
 /// </summary>
 /// <param name="thisReference">The this reference.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(ThisReference thisReference)
 {
     thisReference.Type = this.Substitute(thisReference.Type);
       return thisReference;
 }
 private static List<IStatement> InitializeFieldsInConstructor(IMethodDefinition method) {
   Contract.Ensures(Contract.Result<List<IStatement>>() != null);
   var inits = new List<IStatement>();
   if (method.IsConstructor || method.IsStaticConstructor) {
     var smb = method.Body as ISourceMethodBody;
     if (method.IsStaticConstructor || (smb != null && !FindCtorCall.IsDeferringCtor(method, smb.Block))) {
       var thisExp = new ThisReference() { Type = method.ContainingTypeDefinition, };
       foreach (var f in method.ContainingTypeDefinition.Fields) {
         if (f.IsStatic == method.IsStatic) {
           var a = new Assignment() {
             Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, },
             Target = new TargetExpression() { Definition = f, Instance = method.IsConstructor ? thisExp : null, Type = f.Type },
             Type = f.Type,
           };
           inits.Add(new ExpressionStatement() { Expression = a, });
         }
       }
     }
   }
   return inits;
 }
示例#8
0
    private static NamespaceTypeDefinition DefineMethodHashAttributeType(HostEnvironment host, RootUnitNamespace rootUnitNamespace) {
      Contract.Requires(host != null);
      var internFactory = host.InternFactory;

      #region Define the type
      var methodHashAttributeType = new NamespaceTypeDefinition() {
        BaseClasses = new List<ITypeReference> { host.PlatformType.SystemAttribute, },
        ContainingUnitNamespace = rootUnitNamespace,
        InternFactory = internFactory,
        //IsBeforeFieldInit = true,
        IsClass = true,
        IsPublic = true,
        //IsSealed = true,
        Methods = new List<IMethodDefinition>(1),
        Name = host.NameTable.GetNameFor("MethodHashAttribute"),
        //Layout = LayoutKind.Auto,
        //StringFormat = StringFormatKind.Ansi,
      };
      #endregion

      #region Define the ctor
      var systemVoidType = host.PlatformType.SystemVoid;
      List<IStatement> statements = new List<IStatement>();
      SourceMethodBody body = new SourceMethodBody(host) {
        LocalsAreZeroed = true,
        Block = new BlockStatement() { Statements = statements },
      };

      var ctor = new MethodDefinition() {
        Body = body,
        CallingConvention = CallingConvention.HasThis,
        ContainingTypeDefinition = methodHashAttributeType,
        InternFactory = internFactory,
        IsRuntimeSpecial = true,
        IsStatic = false,
        IsSpecialName = true,
        Name = host.NameTable.Ctor,
        Type = systemVoidType,
        Visibility = TypeMemberVisibility.Public,
      };
      var systemStringType = host.PlatformType.SystemString;
      var systemIntType = host.PlatformType.SystemInt32;
      ctor.Parameters = new List<IParameterDefinition>(){
        new ParameterDefinition() {
          ContainingSignature = ctor,
          Name = host.NameTable.GetNameFor("a"),
          Type = systemStringType,
          Index = 0,
        },
        new ParameterDefinition() {
          ContainingSignature = ctor,
          Name = host.NameTable.GetNameFor("b"),
          Type = systemIntType,
          Index = 1,
        }
      };

      body.MethodDefinition = ctor;
      var thisRef = new ThisReference() { Type = methodHashAttributeType, };
      // base();
      foreach (var baseClass in methodHashAttributeType.BaseClasses) {
        var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() {
          CallingConvention = CallingConvention.HasThis,
          ContainingType = baseClass,
          GenericParameterCount = 0,
          InternFactory = internFactory,
          Name = host.NameTable.Ctor,
          Type = systemVoidType,
        };
        statements.Add(
          new ExpressionStatement() {
            Expression = new MethodCall() {
              MethodToCall = baseCtor,
              IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument?
              ThisArgument = new ThisReference() { Type = methodHashAttributeType, },
              Type = systemVoidType, // REVIEW: Is this the right way to do this?
              Arguments = new List<IExpression>(),
            }
          }
          );
        break;
      }

      // return;
      statements.Add(new ReturnStatement());
      methodHashAttributeType.Methods.Add(ctor);
      #endregion Define the ctor
      return methodHashAttributeType;

    }
示例#9
0
 /// <summary>
 /// Create the new body of the iterator method. 
 /// </summary>
 /// <remarks>
 /// Pseudo code:
 /// iteratorClosureLocal = new Closure(0);
 /// iteratorClosureLocal.field = parameter; // for each parameter including this. 
 /// return iteratorClosureLocal;
 /// </remarks>
 private BlockStatement CreateNewIteratorMethodBody(IteratorClosureInformation iteratorClosure) {
   BlockStatement result = new BlockStatement();
   // iteratorClosureLocal = new IteratorClosure(0);
   LocalDefinition localDefinition = new LocalDefinition() {
     Name = this.host.NameTable.GetNameFor("iteratorClosureLocal"),
     Type = GetClosureTypeReferenceFromIterator(iteratorClosure),
   };
   CreateObjectInstance createObjectInstance = new CreateObjectInstance() {
     MethodToCall = GetMethodReference(iteratorClosure, iteratorClosure.Constructor),
     Type = localDefinition.Type
   };
   // the start state depends on whether the iterator is an IEnumerable or an IEnumerator. For the former,
   // it must be created in state -2. Then it is the GetEnumerator method that puts it into its
   // "start" state, i.e., state 0.
   var startState = this.isEnumerable ? -2 : 0;
   createObjectInstance.Arguments.Add(new CompileTimeConstant() { Value = startState, Type = this.host.PlatformType.SystemInt32 });
   LocalDeclarationStatement localDeclarationStatement = new LocalDeclarationStatement() {
     InitialValue = createObjectInstance,
     LocalVariable = localDefinition
   };
   result.Statements.Add(localDeclarationStatement);
   // Generate assignments to closure instance's fields for each of the parameters captured by the closure. 
   foreach (object capturedLocalOrParameter in FieldForCapturedLocalOrParameter.Keys) {
     BoundField boundField = FieldForCapturedLocalOrParameter[capturedLocalOrParameter];
     Assignment assignment;
     ITypeReference localOrParameterType = GetLocalOrParameterType(capturedLocalOrParameter);
     if (capturedLocalOrParameter is ILocalDefinition) continue;
     if (capturedLocalOrParameter is IThisReference) {
       var thisR = new ThisReference();
       IExpression thisValue = thisR;
       if (!this.method.ContainingTypeDefinition.IsClass) {
         thisValue = new AddressDereference() {
           Address = thisR,
           Type = this.method.ContainingTypeDefinition.IsGeneric ? (ITypeReference)this.method.ContainingTypeDefinition.InstanceType : (ITypeReference)this.method.ContainingTypeDefinition
         };
       }
       assignment = new Assignment {
         Source = thisValue,
         Type = this.method.ContainingType,
         Target = new TargetExpression() {
           Definition = GetFieldReference(iteratorClosure, boundField.Field),
           Type = this.method.ContainingType,
           Instance = new BoundExpression() {
             Type = localDefinition.Type,
             Instance = null,
             Definition = localDefinition,
             IsVolatile = false
           }
         },
       };
     } else {
       assignment = new Assignment {
         Source = new BoundExpression() {
           Definition = capturedLocalOrParameter,
           Instance = null,
           IsVolatile = false,
           Type = localOrParameterType
         },
         Type = localOrParameterType,
         Target = new TargetExpression() {
           Definition = GetFieldReference(iteratorClosure, boundField.Field),
           Type = localOrParameterType,
           Instance = new BoundExpression() {
             Type = localDefinition.Type,
             Instance = null,
             Definition = localDefinition,
             IsVolatile = false
           }
         },
       };
     }
     ExpressionStatement expressionStatement = new ExpressionStatement() { Expression = assignment };
     result.Statements.Add(expressionStatement);
   }
   // Generate: return iteratorClosureLocal;
   result.Statements.Add(new ReturnStatement() {
     Expression = new BoundExpression() { Definition = localDeclarationStatement.LocalVariable, Instance = null, Type = localDeclarationStatement.LocalVariable.Type }
   });
   return result;
 }
示例#10
0
 public override void RewriteChildren(ThisReference thisReference) {
   if (TypeHelper.TypesAreEquivalent(thisReference.Type, this.sourceType))
     thisReference.Type = this.targetType;
 }
示例#11
0
 /// <summary>
 /// Rewrites the children of the given this reference expression.
 /// </summary>
 public virtual void RewriteChildren(ThisReference thisReference)
 {
     this.RewriteChildren((Expression)thisReference);
 }
示例#12
0
 /// <summary>
 /// Visits the specified this reference.
 /// </summary>
 /// <param name="thisReference">The this reference.</param>
 public override void Visit(IThisReference thisReference)
 {
     ThisReference mutableThisReference = thisReference as ThisReference;
     if (alwaysMakeACopy || mutableThisReference == null) mutableThisReference = new ThisReference(thisReference);
     this.resultExpression = this.myCodeMutator.Visit(mutableThisReference);
 }
示例#13
0
 /// <summary>
 /// Visits the specified this reference.
 /// </summary>
 /// <param name="thisReference">The this reference.</param>
 /// <returns></returns>
 public virtual IExpression Visit(ThisReference thisReference)
 {
     thisReference.Type = this.Visit(thisReference.Type);
       return thisReference;
 }