/// <summary> /// A rewriter for CodeModel method bodies, which changes any foreach loops found in the body into lower level structures. /// </summary> /// <param name="host">An object representing the application that is hosting the converter. It is used to obtain access to some global /// objects and services such as the shared name table and the table for interning references.</param> /// <param name="sourceLocationProvider">An object that can map the ILocation objects found in a block of statements to IPrimarySourceLocation objects. May be null.</param> public ForEachRemover(IMetadataHost host, ISourceLocationProvider/*?*/ sourceLocationProvider) : base(host) { this.sourceLocationProvider = sourceLocationProvider; this.moveNext = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = host.PlatformType.SystemCollectionsIEnumerator, InternFactory = host.InternFactory, Name = host.NameTable.GetNameFor("MoveNext"), Parameters = new List<IParameterTypeInformation>(), Type = host.PlatformType.SystemBoolean, }; var assemblyReference = new Immutable.AssemblyReference(this.host, this.host.CoreAssemblySymbolicIdentity); IUnitNamespaceReference ns = new Immutable.RootUnitNamespaceReference(assemblyReference); ns = new Immutable.NestedUnitNamespaceReference(ns, this.host.NameTable.GetNameFor("System")); var iDisposable = new Immutable.NamespaceTypeReference(this.host, ns, this.host.NameTable.GetNameFor("IDisposable"), 0, false, false, true, PrimitiveTypeCode.Reference); this.disposeMethod = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = iDisposable, InternFactory = host.InternFactory, Name = this.host.NameTable.GetNameFor("Dispose"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemVoid, }; }
internal LockReplacer(SourceMethodBody sourceMethodBody) { Contract.Requires(sourceMethodBody != null); this.host = sourceMethodBody.host; Contract.Assume(sourceMethodBody.host != null); this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider; this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(sourceMethodBody.numberOfReferencesToLocal != null); this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(sourceMethodBody.numberOfAssignmentsToLocal != null); this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion != null); var systemThreading = new Immutable.NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace, this.host.NameTable.GetNameFor("Threading")); var systemThreadingMonitor = new Immutable.NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0, isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive); var parameters = new IParameterTypeInformation[2]; this.monitorEnter = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid, this.host.NameTable.GetNameFor("Enter"), 0, parameters); parameters[0] = new SimpleParameterTypeInformation(monitorEnter, 0, this.host.PlatformType.SystemObject); parameters[1] = new SimpleParameterTypeInformation(monitorEnter, 1, this.host.PlatformType.SystemBoolean, isByReference: true); this.monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid, this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject); }
/// <summary> /// If the <paramref name="typeDefinition"/> has a type contract, generate a /// contract invariant method and add it to the Methods of the <paramref name="typeDefinition"/>. /// </summary> private void VisitTypeDefinition(ITypeDefinition typeDefinition) { ITypeContract typeContract = this.contractProvider.GetTypeContractFor(typeDefinition); if (typeContract != null) { #region Define the method List<IStatement> statements = new List<IStatement>(); var methodBody = new SourceMethodBody(this.host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements } }; List<ICustomAttribute> attributes = new List<ICustomAttribute>(); MethodDefinition m = new MethodDefinition() { Attributes = attributes, Body = methodBody, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = typeDefinition, InternFactory = this.host.InternFactory, IsStatic = false, Name = this.host.NameTable.GetNameFor("$InvariantMethod$"), Type = systemVoid, Visibility = TypeMemberVisibility.Private, }; methodBody.MethodDefinition = m; #region Add calls to Contract.Invariant foreach (var inv in typeContract.Invariants) { var methodCall = new MethodCall() { Arguments = new List<IExpression> { inv.Condition, }, IsStaticCall = true, MethodToCall = this.contractProvider.ContractMethods.Invariant, Type = systemVoid, Locations = new List<ILocation>(inv.Locations), }; ExpressionStatement es = new ExpressionStatement() { Expression = methodCall }; statements.Add(es); } statements.Add(new ReturnStatement()); #endregion #region Add [ContractInvariantMethod] var contractInvariantMethodType = new Immutable.NamespaceTypeReference( this.host, this.host.PlatformType.SystemDiagnosticsContractsContract.ContainingUnitNamespace, this.host.NameTable.GetNameFor("ContractInvariantMethodAttribute"), 0, false, false, true, PrimitiveTypeCode.NotPrimitive ); var contractInvariantMethodCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = contractInvariantMethodType, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = host.NameTable.Ctor, Type = host.PlatformType.SystemVoid, }; var contractInvariantMethodAttribute = new CustomAttribute(); contractInvariantMethodAttribute.Constructor = contractInvariantMethodCtor; attributes.Add(contractInvariantMethodAttribute); #endregion var namedTypeDefinition = (NamedTypeDefinition)typeDefinition; var newMethods = new List<IMethodDefinition>(namedTypeDefinition.Methods == null ? 1 : namedTypeDefinition.Methods.Count() + 1); if (namedTypeDefinition.Methods != null) { foreach (var meth in namedTypeDefinition.Methods) { if (!ContractHelper.IsInvariantMethod(this.host, meth)) newMethods.Add(meth); } } namedTypeDefinition.Methods = newMethods; namedTypeDefinition.Methods.Add(m); #endregion Define the method } }